JWT简介& JWT结构& JWT示例& 前端添加JWT令牌功能& 后端程序

目录

1. JWT简述

1.1 什么是JWT

1.2 为什么使用JWT

1.3 JWT结构

1.4 验证过程

2. JWT示例

2.1 后台程序

2.2 前台加入jwt令牌功能


1. JWT简述

1.1 什么是JWT

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案

1.2 为什么使用JWT

传统的intenet服务的认证是通过session进行的,当用户通过了安全认证后,则在服务端的session对象中保存该用户的认证信息,这样该用户对服务的访问被认为是安全的。这种模式的最大问题是没有分布式架构,不方便进行横向扩展,这种模式只适合于单体应用模式。如果需要进行服务集群则需要处理好共享session的问题。 如果一个庞大的系统需要按服务分解为多个独立的服务,使用分布式架构,则这种方式更难处理。使用jwt可以方便的处理上面提到的问题。

1.3 JWT结构

 

JWT头
JWT头部分是一个描述JWT元数据的JSON对象,通常如下所示。{"alg": "HS256","typ": "JWT"}。

有效载荷
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。这些声明被JWT标准称为claims。
例如:{"sub":"123","name":"Tom","admin":true},sub代表这个token的所有人,存储的是所有人的ID;name表示这个所有人的名字;admin表示所有人是否管理员的角色。当后面对JWT进行验证的时候,这些claim都能发挥特定的作用。
根据JWT的标准,这些claims可以分为以下三种类型:
A. Reserved claims(保留)
它的含义就像是编程语言的保留字一样,属于JWT标准里面规定的一些claim。JWT标准里面定义好的claim有:
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

B. Public claims,略(不重要)

C. Private claims(私有)
这个指的就是自定义的claim,比如前面那个示例中的admin和name都属于自定的claim。这些claim跟JWT标准规定的claim区别在于:JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证;而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。
按照JWT标准的说明:保留的claims都是可选的,在生成payload不强制用上面的那些claim,你可以完全按照自己的想法来定义payload的结构,不过这样搞根本没必要:第一是,如果把JWT用于认证, 那么JWT标准内规定的几个claim就足够用了,甚至只需要其中一两个就可以了,假如想往JWT里多存一些用户业务信息,比如角色和用户名等,这倒是用自定义的claim来添加;第二是,JWT标准里面针对它自己规定的claim都提供了有详细的验证规则描述,每个实现库都会参照这个描述来提供JWT的验证实现,所以如果是自定义的claim名称,那么你用到的实现库就不会主动去验证这些claim。

signature
签名的作用是防篡改。签名是把header和payload对应的json结构进行base64url编码之后得到的两个串用英文句点号拼接起来,然后根据header里面alg指定的签名算法生成出来的。算法不同,签名结果不同。以alg: HS256为例来说明前面的签名如何来得到。照前面alg可用值的说明,HS256其实包含的是两种算法:HMAC算法和SHA256算法,前者用于生成摘要,后者用于对摘要进行数字签名。这两个算法也可以用HMACSHA256来统称

JWT实际结构示例:
eyJhbGciOiJIUzI1NiJ9. eyJzdWIiOiJ7fSIsImlzcyI6InpraW5nIiwiZXhwIjoxNTYyODUwMjM3LCJpYXQiOjE1NjI4NDg0MzcsImp0aSI6ImM5OWEyMzRmMDc4NzQyZWE4YjlmYThlYmYzY2VhNjBlIiwidXNlcm5hbWUiOiJ6c3MifQ. WUfqhFTeGzUZCpCfz5eeEpBXBZ8-lYg1htp-t7wD3I4

1.4 验证过程

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中,此后在于服务器的交互中都携带者JWT信息,它验证的方法其实很简单,只要把header做base64url解码,就能知道JWT用的什么算法做的签名,然后用这个算法,再次用同样的逻辑对header和payload做一次签名,并比较这个签名是否与JWT本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串。

2. JWT示例

2.1 后台程序

1)将资料中src目录下的代码(CorsFilter.java,JwtFilter.java,JwtUtils.java)拷入项目的util目录下(可以根据项目设置的目录结构调整)。
2)程序的解释详见代码中的注释
3)在web.xml中配置JwtFilter过滤器
4)在用户登录验证成功后,需要为该用户生成jwt令牌,具体实现可参考UserAction.java
5)测试后台的验证服务,确定在验证通过的前提下可以正确的生成jwt令牌。

2.2 前台加入jwt令牌功能

1) 在store/state.js中加入jwt变量

//存放全局参数的容器,组件可以通过state.js获取全局参数
const state = {
  LeftAsideState: 'open',
  PersonName:'张飞',
  
  //存放jwt令牌
  jwt:null
}

export default state

2)在store/mutations.js中加入设置jwt方法

  //设置JWT令牌
  setJwtToken: (state, payload) => {
    state.jwt = payload.jwt;
  }

3)在store/getters.js中加入获取jwt的方法

  //获取jwt令牌
  getJwtToken: function(state) {
    return state.jwt;
  }

4)修改main.js应用入口

//将vue实例赋给window.vm属性,以便于在http.js的响应拦截器和请求拦截器中获取vue实例
window.vm = new Vue({
  el: '#app',
  router,
  store,
  components: {App},
  template: '<App/>'
})

5)完善api/http.js中的请求拦截器和响应拦截器

// 请求拦截器
axios.interceptors.request.use(function(config) {
  //获取store中的jwt令牌,如果正常获取,将其放入请求头,
  //在调用后台服务时,服务会通过过滤器验证jwt令牌的有效性
  //如果没有令牌或令牌无效则拒绝服务。
  let jwt = window.vm.$store.getters.getJwtToken;
  if(jwt) {
    config.headers['jwt'] = jwt;
  }
  return config;
}, function(error) {
  return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(function(response) {
  //获取响应头中的jwt令牌数据(认证服务将生成的令牌放入header的jwt属性中)
  //如果获取到jwt令牌,在保存到store中,以后发送请求时需要将令牌放入请求头
  let jwt = response.headers['jwt'];
  if(jwt) {
	  window.vm.$store.commit('setJwtToken',{jwt:jwt});
  }
  return response;
}, function(error) {
  return Promise.reject(error);
});

完毕,测试 

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
使用JWT令牌实现登录功能可以增加系统的安全性和可扩展性。下面是一个基本的实现过程: 1. 用户通过用户名和密码进行登录请求。 2. 服务器验证用户的身份,并生成一个JWT令牌。 3. 服务器将JWT令牌发送给客户端作为登录凭证。 4. 客户端在后续的请求中将JWT令牌携带在请求头或者请求参数中。 5. 服务器在接收到请求时验证JWT令牌的有效性和签名。 6. 如果JWT令牌有效,则处理请求;否则,返回未授权的错误。 下面是一个示例代码(使用Node.js和jsonwebtoken库): ```javascript const jwt = require('jsonwebtoken'); // 登录处理 function login(username, password) { // 验证用户名和密码,生成用户对象 const user = authenticateUser(username, password); if (user) { // 生成JWT令牌 const token = jwt.sign({ id: user.id }, 'your_secret_key', { expiresIn: '1h' }); return token; } else { throw new Error('Invalid username or password'); } } // 请求处理中间件 function authenticateToken(req, res, next) { // 获取请求头中的Authorization字段 const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token == null) { return res.sendStatus(401); // 未授权 } // 验证JWT令牌 jwt.verify(token, 'your_secret_key', (err, user) => { if (err) { return res.sendStatus(403); // 令牌无效 } req.user = user; next(); // 验证通过,继续处理请求 }); } // 示例路由,需要进行身份验证 app.get('/protected', authenticateToken, (req, res) => { res.send('Protected data'); }); ``` 在上面的示例中,`login`函数用于生成JWT令牌。`authenticateToken`函数是一个请求处理中间件,用于验证JWT令牌的有效性。 注意,在实际使用中,你需要替换示例中的`your_secret_key`为一个安全的密钥,并根据自己的需求进行相应的调整。 希望这个例子能够帮到你,如果有更多问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑶大头*^_^*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值