我不完全确定这个系统是如何设置的,以及 JWT 的 cookie 中间件是如何工作的,从 angular-univeristy 教程的评论部分,我可以看到有人评论了 authorizaiton 标头也不起作用,结论是
Safari needs an ending slash on the API's for the Authorization Header to be appended...
Where chrome doesn't need the ending slash and can always add API Headers.
I've appended the slash and it's also working on mobile devices now!
我会说如果 cookie 让您头疼,也许没有必要。cookie 可以很好地存储会话,但也有很多法律管理隐私,您需要告知用户该网站使用 cookie,就像在“授权”标头中使用 JWT 一样可以完成身份验证和授权。
考虑以下使用 express 的中间件
import express from 'express';
import cors from 'cors';
import jwt from 'jsonwebtoken';
const app = express();
const JWT_SECRET = 'Your Secret';
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.set('trust proxy', true);
app.disable('x-powered-by');
app.use(cors());
// This can throw an error so always catch it!
function decodeJWT(token) {
return new Promise((resolve, reject) => {
jwt.verify(token, JWT_SECRET, (err, obj) => {
if (err) return reject(err);
return resolve(obj);
});
});
}
function encodeJWT(payload, options = { expiresIn: '30d' }) {
return new Promise((resolve, reject) => {
jwt.sign(payload, JWT_SECRET, options, (err, token) => {
if (err) return reject(err);
return resolve(token);
});
});
}
// This is a middleware function that will activate
// from every request that is sent to the server
// The Angular application can read and write to the 'Authorization' header
app.use(async(req, res, next) => {
const JWT_TOKEN = req.header('Authorization');
if (JWT_TOKEN) {
try {
// This is the custom property we add to the request
// Adding this property we can check if the JWT token exists
// in other API end points of our Express application
// if this verification does not throw an error, it is valid
// otherwise, the token will not exist in other API points
req.JWT = await decodeJWT(JWT_TOKEN);
res.setHeader('Authroization', JWT_TOKEN)
} catch (err) {
console.error(err);
delete req.JWT;
res.removeHeader('Authorization');
}
}
next();
});
// Declare all rest API below the middleware
app.post('/api/login', async(req, res, next) => {
const email = req.body.email;
const password = req.body.password;
if (email && password) { // Custom validation can be implemented here
try {
const JWT_TOKEN = await encodeJWT({ email: email, auth: true });
res.setHeader('Authorization', JWT_TOKEN);
return res.status(200).json(JWT_TOKEN);
} catch (err) {
return res.sendStatus(500).json(err);
}
}
res.sendStatus(401).send("Email or Password invalid!");
});
app.get('/api/members/only', (req, res, next) => {
if (req.JWT) { // Or if req.JWT.auth === true
return res.status(200).send('Hello world!');
}
return res.status(401).send('Access Denied');
});
app.listen(8080, () => conosle.log('app listening'));
在您的 Angular 应用程序中,您可以使用电子邮件和密码发布到 /api/login 路由,并接收 JWT 令牌以在“授权”标头中设置。
Angular 中的授权服务可能如下所示
@Injectable()
export class AuthService {
constructor(private http: HttpClient) {
}
async login(email: string, password: string) {
let JWT = await this.http.post('/api/login', {email, password});
localStorage.set('Authorization', JWT);
return JWT;
}
logout() {
return localStorage.removeItem('Authorization');
}
membersArea() {
// Also consider a HTTP Interceptor instead of manually setting the headers
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', localStorage.getItem('Authorization'));
let options = new RequestOptions({ headers: headers });
return this.http.get('/api/members/only', options);
}
}
希望对你有帮助