我在正面的我的角度应用程序和背面的NodeJ中使用bcrypt
和jwt
进行身份验证。我将令牌存储在用户本地存储中,现在我设法从本地存储中存储和接收令牌,并在刷新后对用户进行身份验证,但是我也想从服务器获取信息,我尝试了几种方法,但我没有确定实现此目标的最佳方法是
我的节点路线
router.post("/login", (req, res, next) => {
let fetchedUser;
User.findOne({ email: req.body.email })
.then(user => {
console.log(user)
if (!user) {
return res.status(401).json({
message: "Auth failed"
});
}
fetchedUser = user;
return bcrypt.compare(req.body.password, user.password);
})
.then(result => {
if (!result) {
return res.status(401).json({
message: "Auth failed"
});
}
const token = jwt.sign(
{ email: fetchedUser.email, userId: fetchedUser._id },
"this_is_the_secret",
{ expiresIn: "1h" }
);
res.status(200).json({
token: token,
expiresIn: 3600,
isAdmin:fetchedUser.admin,
user: fetchedUser
});
})
.catch(err => {
return res.status(401).json({
message: "Auth failed"
});
});
});
我的服务:
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Subject } from "rxjs";
import { Router } from "@angular/router";
import { SignUpData } from "../models/sign-up.model";
import { LogInData } from "../models/log-in.model";
@Injectable({ providedIn: "root"})
export class AuthService {
private isAuthenticated = false
private token: string
private authStatusListner = new Subject<boolean>()
private tokenTimer: any
private isAdmin = false
private userInfo: any
signupUrl = "http://localhost:3000/signup";
loginUrl = "http://localhost:3000/login"
constructor(private http: HttpClient,
private router:Router){}
getToken(){
return this.token
}
checkIfAdmin(){
return this.isAdmin
}
getUserInfo(){
if(this.token){
return this.userInfo
}
}
getAuthStatus(){
return this.isAuthenticated
}
getAuthStatusListner(){
return this.authStatusListner.asObservable()
}
createUser(name: string, email: string, password:string){
const authData: SignUpData = {name:name, email: email, password: password}
this.http.post(this.signupUrl, authData)
.subscribe(response => {
});
}
login(email: string, password){
const authData: LogInData = {email: email, password: password}
this.http.post<{token: string, expiresIn: number, isAdmin: boolean, user: any}>(this.loginUrl,authData)
.subscribe(response => {
const token = response.token
this.token = token;
if(token){
if(response.isAdmin){
this.isAdmin = response.isAdmin
}
this.userInfo = response.user
const expiersInDuration = response.expiresIn
this.setAuthTimer(expiersInDuration)
this.isAuthenticated = true
this.authStatusListner.next(true);
const now = new Date;
const expirationDate = new Date (now.getTime() + expiersInDuration * 1000)
this.saveAuthData(token,expirationDate,this.userInfo.email)
this.router.navigate(['/user'])
}
});
}
// Cheacking if the user have the login token in the local storage for autoLogin and the exparation date
autoAuthUser(){
const AuthInformation = this.getAuthData()
if (!AuthInformation){
return
}
const now = new Date();
const expairesIn = AuthInformation.expirationDate.getTime() - now.getTime();
if (expairesIn > 0){
this.token = AuthInformation.token
this.isAuthenticated = true
this.setAuthTimer(expairesIn / 1000)
this.authStatusListner.next(true)
this.login(AuthInformation.email, AuthInformation.token)
}
}
// User logout
logout(){
this.token = null
this.isAuthenticated = false
this.isAdmin = false
this.authStatusListner.next(false)
clearTimeout(this.tokenTimer)
this.clearAuthData()
this.router.navigate(['/user'])
}
// Setting the timer for the token expiration
private setAuthTimer(duration: number){
this.tokenTimer = setTimeout(() => {
this.logout();
}, duration * 1000)
}
// Setting the Auth token in the local storage
private saveAuthData(token: string, expirationDate: Date, email:string){
console.log(token)
localStorage.setItem("email", email )
localStorage.setItem("token", token)
localStorage.setItem("expiration", expirationDate.toISOString())
}
// Clearing the token from local storage in logout
private clearAuthData(){
localStorage.removeItem('email')
localStorage.removeItem('token')
localStorage.removeItem('expiration')
}
// Geting the login token if it exist in the user local storage
private getAuthData(){
const email = localStorage.getItem("email")
const token = localStorage.getItem("token");
const expirationDate = localStorage.getItem("expiration")
if (!token || !expirationDate){
return
}
return {
email: email,
token: token,
expirationDate: new Date(expirationDate)
}
}
}
答案 0 :(得分:0)
实现此功能的标准方法是以与现在相同的方式存储和检索用户令牌。
您的autoAuthUser
函数在检索用户令牌后,应使用令牌作为授权标头向服务器发送GET
请求(或者,您当前正在为任何授权请求设置令牌)。即
const headers = new Headers({ 'authorization': this.token });
this.http.get<{ user: any }>(this.getUserUrl, { headers }).subscribe(...)
您的后端应根据服务器存储令牌的位置对令牌进行身份验证(我假设是数据库),并返回根据令牌存储的用户信息。您当然不应该使用与登录相同的路由。