我试图让导航栏显示登录并仅在用户未登录时注册按钮,并在用户登录时显示消息和配置文件导航项。
这是代码:
令牌服务
...
SetToken(token) {
this.cookieService.set('chat_token', token);
}
GetToken() {
return this.cookieService.get('chat_token');
}
DeleteToken() {
this.cookieService.delete('chat_token');
}
GetPayload() {
const token = this.GetToken();
let payload;
if (token) {
payload = token.split('.')[1];
payload = JSON.parse(window.atob(payload));
}
return payload.data;
}
}
Authguard服务
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
const token = this.tokenService.GetToken();
if (token) {
return true;
} else {
this.router.navigate(['/']);
return false;
}
}
}
header.ts
constructor(public nav: HeaderService, private tokenService: TokenService,
private router: Router,
private usersService: UsersService,
private msgService: MessageService
) {
this.socket = io('http://localhost:3000');
}
ngOnInit() {
this.user = this.tokenService.GetPayload();
...
HTML
<nav *ngIf="nav.visible" class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">
<img src="../assets/images/close.png" class="img-fluid" style="width:50px; height:50px" alt="">
</a>
<button class="navbar-toggler" type="button"
(click)="toggleNavbar()">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse"
[ngClass]="{ 'show': navbarOpen }">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" routerLink="/home" >Item 1</a>
</li>
<li class="nav-item signin">
<a class="nav-link" routerLink="/sign-in" >Sign in</a>
</li>
<li class="nav-item signup">
<a class="nav-link" routerLink="/sign-up" >Sign Up</a>
</li>
<li class="nav-item dropdown ml-auto" appdropdown #r="appdropdown">
<a class="nav-link dropdown-toggle toolbar-image" href="" onclick="return false;" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">forum</i>
<span>2</span>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
<div class="sidebar-scroll" id="list-group">
<a class="dropdown-item chat" href="#">
<img src="http://emilcarlsson.se/assets/donnapaulsen.png" class="rounded-circle">
<div class='message'>
<h3 class="d-xs-none username">Jessica</h3>
<p class="d-xs-none letter">StanIsLove aaaaaaaaaaaaaaaaa.</p>
</div>
<p>17m ago</p>
</a>
</div>
</div>
</li>
<li class="nav-item dropdown ml-auto" appdropdown #r="appdropdown">
<a class="nav-link dropdown-toggle" href="" onclick="return false;" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img src="http://emilcarlsson.se/assets/donnapaulsen.png" class="rounded-circle profile">
</a>
<div class="dropdown-menu dropdown-menu-right avatar" aria-labelledby="navbarDropdownMenuLink">
<div class="sidebar-scroll" id="list-group">
<a class="dropdown-item chat" href="#">
<span class="d-xs-none username">Profile</span>
</a>
<a class="dropdown-item chat" href="#">
<span class="d-xs-none username">Settings</span>
</a>
<a class="dropdown-item chat" href="#">
<span class="d-xs-none username">Logout</span>
</a>
</div>
</div>
</li>
</ul>
</div>
</nav>
我假设我应该在HTML中集成this.tokenService.GetPayload()并使用ng,但不确定它是否可行。如何解决此问题并仅为外部用户显示登录和注册链接,并仅显示已登录用户的最后2个下拉菜单?
1.)你需要避免在component's methods
中调用html template
。可以找到here的解释
2.)在你的header-component.ts
中,将你的服务注入构造函数,添加一个类属性,调用你的服务来获取令牌并相应地设置你的类属性。
export clas HeaderComponent implements OnInit:
private isLogged: boolean;
constructor(private tokenService: TokenService){
public ngOnInit() {
this.isLogged = this.tokenService.GetPayload() !== null; // here, I consider that user is logged if you have a payload, maybe you need to change the condition
}
}
3.)在header.component.html
内,检查用户是否已登录以显示您的元素。
<div *ngIf="isLogged">...</div>
4.)您的方法GetPayload()应该被修改。如果您没有令牌,您的代码将抛出TypeError: Cannot read property data of undefined
GetPayload() {
const token = this.GetToken();
if (!token) {
return null;
}
const payload = Json.parse(window.atob(token.split('.')[1]);
return payload.data;
}
既然你的方法GetPayload可以返回null,那么在调用方法时要小心,确保在使用之前结果不为null。
您可以使用检查用户是否已登录以完全禁用/隐藏链接。此检查应由服务器发送到您的客户端,并且应该有一个服务,其中包含任何组件要求的登录状态。在您的情况下,您可以在标签内添加结构指令*ngIf="user"
以检查用户是否已设置,并且仅在设置时显示链接。
<li *ngIf="user" class="nav-item">
<a class="nav-link" routerLink="/home" >Item 1</a>
</li>
如果您只想保护路由,请使用AuthGuard。 https://angular.io/guide/router#canactivate-requiring-authentication。