2024年鸿蒙最新nodejs使用JWT(全)_nodejs jwt(1),阿里五次面试

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


同样进行Base64编码后,字符串如下:



eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ



> 
> 请注意,**默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中**,以防止信息泄露。**JWT只是适合在网络中传输一些非敏感的信息**
> 
> 
> 


### Signature


签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名



Signature = HMACSHA256(base64Url(header)+.+base64Url(payload),secretKey)


一旦前面两部分数据被篡改,只要服务器加密用的密钥没有泄露,得到的签名肯定和之前的签名不一致


在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用`.`分隔,就构成整个JWT对象  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/2831644abac59cffc5d203f6fb0636d1.png#pic_center)


注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:


* header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
* signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值


## 如何实现


`Token`的使用分成了两部分:


* 生成token:登录成功的时候,颁发token
* 验证token:访问某些资源或者接口时,验证token


### 生成 token


借助第三方库`jsonwebtoken`,通过`jsonwebtoken` 的 `sign` 方法生成一个 `token`:



const jwt = require(‘jsonwebtoken’);

jwt.sign(Payload, secretkey, option)


* 第一个参数指的是 Payload
* 第二个是秘钥,服务端特有
* 第三个参数是 option,可以定义 token 过期时间,单位是秒


### 校验token


使用 `jwt.verify(token, secretkey, (error, data)=>{})` 进行验证


* secret 必须和 sign 时候保持一致


### 登录注册实例


#### 服务端


##### 定义生成token和校验token的函数


创建jwt.js模块,定义生成token和校验token的函数



const jwt = require(‘jsonwebtoken’);
const secretkey = ‘howdoyoudo’; //密钥

// 生成token
const sign = (data={}) => {
return jwt.sign(data, secretkey, {
expiresIn: 60*60,
});
};

// 验证token
const verify = (req, res, next) => {
let authorization = req.headers.authorization || req.body.token || req.query.token || ‘’;
let token = ‘’;
if (authorization.includes(‘Bearer’)) {
token = authorization.replace('Bearer ', ‘’);
} else {
token = authorization;
}

jwt.verify(token, secretkey, (error, data) => {
if (error) {
res.json({ error: 1, data: ‘token验证失败’ });
} else {
req._id = data._id;
next();
}
});
};

module.exports = {
sign,
verify,
};


##### 登录成功生成token



const router = require(‘express’).Router();
const md5 = require(‘md5’);

const User = require(‘…/modules/user’);
const jwt = require(‘…/modules/jwt’);

// 登录成功生成token
router.post(‘/login’, (req, res)=>{
User
.findOne({username:req.body.username})
.exec()
.then(data=>{
if (data) {
if (data.password == md5(req.body.password)) {
res.json({
error:0,
data: ‘登录成功’,
token: jwt.sign({ _id: data._id }),// 生成token,并传入用户_id
});
}else{
res.json({error:1, data: ‘密码错误’});
}
} else {
res.json({error:1, data: ‘用户名不存在,请先注册’});
}
});
});


##### 在需要登录验证的方法中挂载验证函数



router.get(‘/user’, jwt.verify, (req, res)=>{
User.findOne({_id: req._id}).exec().then(data=>{
res.json({
error: 0,
data: JSON.parse(JSON.stringify(data))
});
});
});


#### 客户端


##### 登录成功保存token


在客户端接收到`token`后,一般情况会通过`localStorage`进行缓存



localStorage.setItem(‘token’, data.token);


##### 请求的过程中携带token


然后将`token`放到`HTTP`请求头`Authorization` 中,关于`Authorization` 的设置,前面要加上 [Bearer](https://bbs.csdn.net/topics/618636735) ,注意后面带有空格:


[JWT规范](https://bbs.csdn.net/topics/618636735)



axios({
method: ‘GET’,
url: ‘/user’,
headers: {
Authorization: localStorage.getItem(‘token’) ? ‘Bearer ’ + localStorage.getItem(‘token’) : ‘’,
}
}).then(res => {
$(’#login-box’).html(template(‘login-template’, res.data))
});


## session 和 jwt 对比


基于 session 都是需要服务端存储的,而 JWT 是不需要服务端来存储的,总结如下:


**1、基于 session 和 cookie 的认证和鉴权模式有什么好与不好的地方呢?**


缺点 :


1. 容易遇到跨域问题。不同域名下是无法通过 session 直接来做到认证和鉴权的。
2. 分布式部署的系统,需要使用共享 session 机制
3. 容易出现 [CSRF](https://bbs.csdn.net/topics/618636735) 问题。


优点:


1. 方便灵活,服务器端直接创建一个 sessionid,下发给客户端,客户端请求携带 sessionid 即可。
2. session 存储在服务端,更加安全。
3. 便于服务端清除 session,让用户重新授权一次。


**2、JWT 与 session 有什么区别呢?**


JWT 是基于客户端存储的一种认证方式,然而 session 是基于服务端存储的一种认证方式


优点:


* JWT具有通用性,所以可以跨域
* 组成简单,字节占用小,便于传输
* 服务端无需保存会话信息,很容易进行水平扩展
* 一处生成,多处使用,可以在分布式系统中,解决单点登录问题
* 可防护[CSRF](https://bbs.csdn.net/topics/618636735)攻击


缺点:


* 无法清除认证 token。由于 JWT 生成的 token 都是存储在客户端的,不能有服务端去主动清除,只有直到失效时间到了才能清除。除非服务端的逻辑做了改变。
* 存储在客户端,相对服务端,安全性更低一些。当 JWT 生成的 token 被破解,我们不便于清除该 token。
* payload部分仅仅是进行简单编码,所以只能用于存储逻辑必需的非敏感信息
* 需要保护好加密密钥,一旦泄露后果不堪设想
* 为避免token被劫持,最好使用https协议


**html用户界面代码:**



  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值