我尝试了多种方法来实现这一点,我的问题是当我第一次登录时,用户界面没有反映我已登录。我必须刷新页面才能显示我的个人资料图片/用户名。< /p>
API:
router.get('/login', (req, res) => {
if (req.user) {
const token = jwt.sign({ userId: req.user.user_id, discordId: req.user.discord_id },
process.env.COOKIE_SECRET);
res.status(200).json({
token: token,
expiresIn: 3600,
user: req.user
});
} else {
res.send('not logged in!')
}
});
router.get('/signedin', isAuthorized, (req, res) => {
if (req.user) {
res.json({
authenticated: true,
user_id: req.user.discord_id
});
}
});
我的服务:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Subject } from 'rxjs';
import { Router } from '@angular/router';
import { CommonService } from '../service/common.service';
import { tap } from 'rxjs/operators';
interface SignedinResponse {
authenticated: boolean;
user_id: string;
}
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
signedin$ = new BehaviorSubject(false);
private userInfo: any;
private userId: string;
private discordId: string;
private token: string;
private tokenTimer: any;
private isAuthenticated = false;
public authStatusListener = new Subject<boolean>();
constructor(private http: HttpClient,
private router: Router,
private commonService: CommonService) { }
getToken() {
return this.token;
}
getIsAuth() {
return this.isAuthenticated;
}
getUserId() {
return this.userId;
}
getUserInfo() {
return this.userInfo
}
getDiscordId() {
return this.discordId;
}
getAuthStatusListener() {
return this.authStatusListener.asObservable();
}
login() {
this.commonService.showLoadingOverlay();
return this.http.get('/auth/login/').subscribe((data: any) => {
const token = data.token;
this.token = token;
if (token) {
this.signedin$.next(true);
this.userInfo = data.user;
this.userId = data.user.user_id;
this.discordId = data.user.discord_id;
this.authStatusListener.next(true);
this.isAuthenticated = true;
const expiresInDuration = data.expiresIn;
const now = new Date();
const expirationDate = new Date(now.getTime() + expiresInDuration * 10000);
this.saveAuthData(token, expirationDate, this.userId, this.userInfo);
this.setAuthTimer(expiresInDuration);
this.commonService.hideLoadingOverlay();
this.router.navigate(['/']);
}
}, error => {
this.commonService.hideLoadingOverlay();
this.router.navigate(['/'])
const message = 'Not logged in...'
this.commonService.showErrorMessage(message);
}
)
}
private saveAuthData(token: string, expirationDate: Date, userId: string, userInfo: any) {
localStorage.setItem("token", token);
localStorage.setItem("expiration", expirationDate.toISOString());
localStorage.setItem("userId", userId);
localStorage.setItem("userInfo", JSON.stringify(userInfo));
}
private clearAuthData() {
localStorage.removeItem("token");
localStorage.removeItem("expiration");
localStorage.removeItem("userId");
localStorage.removeItem("userInfo");
}
autoAuthUser() {
const authInformation = this.getAuthData();
if (!authInformation) {
return;
}
const now = new Date();
const expiresIn = authInformation.expirationDate.getTime() - now.getTime();
if (expiresIn > 0) {
this.token = authInformation.token;
this.isAuthenticated = true;
this.userId = authInformation.userId;
this.userInfo = authInformation.userInfo;
this.setAuthTimer(expiresIn / 1000);
this.authStatusListener.next(true);
}
}
private setAuthTimer(duration: number) {
this.tokenTimer = setTimeout(() => {
this.logout();
}, duration * 1000);
}
private getAuthData() {
const token = localStorage.getItem("token");
const expirationDate = localStorage.getItem("expiration");
const userId = localStorage.getItem("userId");
const userInfo = JSON.parse(localStorage.getItem("userInfo"));
if (!token || !expirationDate) {
return;
}
return {
token: token,
expirationDate: new Date(expirationDate),
userId: userId,
userInfo: userInfo
}
}
logout() {
this.commonService.showLoadingOverlay();
this.token = null;
this.isAuthenticated = false;
this.authStatusListener.next(false);
this.userId = null;
this.userInfo = null;
clearTimeout(this.tokenTimer);
this.clearAuthData();
this.router.navigate(["/"]);
return this.http.get('/auth/logout').subscribe((data: any) => {
this.signedin$.next(false);
this.commonService.hideLoadingOverlay();
this.commonService.showSuccessMessage('Logged out!');
}, error => {
this.commonService.hideLoadingOverlay();
this.commonService.showErrorMessage('Please refresh the page.');
})
}
checkAuth() {
return this.http
.get<SignedinResponse>(`/auth/signedin`)
.pipe(
tap(({ authenticated }) => {
this.signedin$.next(authenticated);
})
);
}
}
获取不和谐用户服务:
getDiscordUser() {
return this.http.get<{id: string, avatar: string, username:string}>('/discordapi/user/');
}
component.ts :
import { Component, OnDestroy, OnInit } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
import { AuthenticationService } from '../core/authentication/authentication.service';
import { ShellService } from './shell.service';
import { CommonService } from '../core/service/common.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-shell',
templateUrl: './shell.component.html',
styleUrls: ['./shell.component.scss']
})
export class ShellComponent implements OnInit {
signedin = false;
userId: any;
userInfo: any;
discordUser: any;
isAdmin = false;
roleList;
constructor(private breakpointObserver: BreakpointObserver,
private authService: AuthenticationService,
private shellService: ShellService,
private commonService: CommonService,
private router: Router) { }
ngOnInit() {
this.authService.signedin$.subscribe(signedin => {
this.signedin = signedin;
console.log(this.signedin);
this.userInfo = this.authService.getUserInfo();
//Get Discord User
this.commonService.getDiscordUser().subscribe((data: any) => {
console.log(data);
this.discordUser = data;
if (this.signedin && this.userInfo) {
this.checkUser();
}
}, error => {
this.commonService.showErrorMessage(error.message);
this.commonService.hideLoadingOverlay();
});
}, error => {
this.commonService.hideLoadingOverlay();
this.commonService.showErrorMessage(error);
})
this.authService.checkAuth().subscribe(() => { });
}
checkUser() {
this.commonService.showLoadingOverlay();
// Check role
this.shellService.getRole().subscribe((data: any) => {
this.roleList = data.role;
if (this.roleList.some(e => e.admin_code === this.userInfo.discord_id)) {
this.isAdmin = true;
}
this.commonService.hideLoadingOverlay();
}, error => {
this.commonService.showErrorMessage(error.message);
this.commonService.hideLoadingOverlay();
});
}
onLogout() {
this.authService.logout();
this.isAdmin = false;
}
}
该应用在登录时不保持登录状态,我必须在登录后刷新页面才能看到我已登录