use*_*664 1 reactjs asp.net-core
我是新手,我正在尝试根据当前用户的角色显示或不显示导航菜单项。在 NavMenu.js (@if(User.IsInRole("Admin"))) 中执行此类操作的正确方法是什么:
render() {
return (
<header>
<Navbar className="navbar-custom navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3" light>
<Container>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
<ul className="navbar-nav flex-grow">
@if(User.IsInRole("Admin"))
{
<NavItem>
<NavLink tag={Link} to="/">Home</NavLink>
</NavItem>
}
<NavItem>
<NavLink tag={Link} to="/counter">Counter</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to="/fetch-data">Fetch data</NavLink>
</NavItem>
<LoginMenu>
</LoginMenu>
</ul>
</Collapse>
</Container>
</Navbar>
</header>
);
}
Run Code Online (Sandbox Code Playgroud)
是否可以使用 ClientApp/src/components/api-authorization 目录中的内置 AuthorizeService.js?
首先,你需要配置你的IdentityServer,将角色信息添加到token中。然后你可以在React中获取角色user.Profile。最后,使用三目表达基于角色显示内容
1.ProfileService在asp.net core端创建自定义类。
public class ProfileService : IProfileService
{
protected UserManager<ApplicationUser> mUserManager;
public ProfileService(UserManager<ApplicationUser> userManager)
{
mUserManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
ApplicationUser user = await mUserManager.GetUserAsync(context.Subject);
IList<string> roles = await mUserManager.GetRolesAsync(user);
IList<Claim> roleClaims = new List<Claim>();
foreach (string role in roles)
{
roleClaims.Add(new Claim(JwtClaimTypes.Role, role));
}
context.IssuedClaims.Add(new Claim(JwtClaimTypes.Name, user.UserName));
context.IssuedClaims.AddRange(roleClaims);
//Add more claims as you need
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
2.报名 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddTransient<IProfileService, ProfileService>();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
Run Code Online (Sandbox Code Playgroud)
3.修改你的 NavMenu.js
import React, { Component } from 'react';
import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
import { LoginMenu } from './api-authorization/LoginMenu';
import './NavMenu.css';
import authService from './api-authorization/AuthorizeService';
export class NavMenu extends Component {
static displayName = NavMenu.name;
constructor (props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true,
isAuthenticated: false,
role: null
};
}
componentDidMount() {
this._subscription = authService.subscribe(() => this.populateState());
this.populateState();
}
componentWillUnmount() {
authService.unsubscribe(this._subscription);
}
async populateState() {
const [isAuthenticated, user] = await Promise.all([authService.isAuthenticated(), authService.getUser()])
this.setState({
isAuthenticated,
role: user && user.role
});
}
toggleNavbar () {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
const role = this.state.role;
return (
<header>
<Navbar className="navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3" light>
<Container>
<NavbarBrand tag={Link} to="/">ReactCore31</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
<ul className="navbar-nav flex-grow">
{
role && role.includes("Admin") ?
<span>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/">Home</NavLink>
</NavItem>
</span>
: null}
<NavItem>
<NavLink tag={Link} className="text-dark" to="/counter">Counter</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} className="text-dark" to="/fetch-data">Fetch data</NavLink>
</NavItem>
<LoginMenu>
</LoginMenu>
</ul>
</Collapse>
</Container>
</Navbar>
</header>
);
}
}
Run Code Online (Sandbox Code Playgroud)
4. AuthorizeService.js(无变化)
async isAuthenticated() {
const user = await this.getUser();
return !!user;
}
async getUser() {
if (this._user && this._user.profile) {
return this._user.profile;
}
await this.ensureUserManagerInitialized();
const user = await this.userManager.getUser();
return user && user.profile;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1140 次 |
| 最近记录: |