SPA登录实现+JWT生成Token+cookie携带Token+代码

本文探讨了在SPA(单页应用)中使用JSON Web Tokens(JWT)进行身份验证的场景,强调JWT在用户身份验证和信息交换中的作用。解释了JWT的结构,包括头、有效载荷和签名部分,并提供了生成和存储JWT的策略,建议在cookie中存储以提高安全性。文中还提到了JWT在SPA登录实现中的应用,并提及了使用JWT时的注意事项,如防止XSS攻击和保持无状态设计。
摘要由CSDN通过智能技术生成

文章目录


##理论知识
前言:本人承诺,本文是在查阅了大量资料并且实践了之后的用心写作。
###Token
理论参考: SSO单点登录使用token机制来验证用户的安全性
###JWT
JWT: 官网

每次您使用令牌对用户进行身份验证时,您的服务器必须验证令牌是否使用您的密钥签名。

摘要:
什么时候应该使用JSON Web令牌?
以下是JSON Web Tokens有用的一些场景:

  • 如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。
  • 身份验证:这是使用JWT最常见的情况。一旦用户登录,每个后续请求都将包含JWT,允许用户访问该令牌允许的路由,服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小,并且能够轻松地跨不同域使用。
  • 信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为JWT可以签名 - 例如使用公钥/私钥对,所以可以确定发件人是他们自称的人。此外,由于使用标头和有效载荷计算签名,因此您还可以验证内容是否未被篡改。
  • Cookie配合Session的机制,使得服务端维护”状态“,这与现在无状态后台设计思路相悖,比如RESTful设计,鼓励无状态;Session的存在也使得后端服务负载均衡相对麻烦,session粘连或者session复制都不是特别好的方案,个人觉得中小型项目,JWT配合RESTful相当方便。[4]

什么是JSON Web令牌结构?

在紧凑的形式中,JSON Web Tokens包含三个由点(.)分隔的部分,它们是:

Header(头)
Payload(有效载荷)
Signature(签名)

因此,JWT通常看起来如下所示。

xxxxx.yyyyy.zzzzz
这里写图片描述

代码形式解释生成token:

	String base64Header = Base64.encodeBase64URLSafeString(header.getBytes());
    String base64Claim = Base64.encodeBase64URLSafeString(claim.getBytes());
    String signature = ShaUtil.Hmacsha256(base64Header + "." + base64Claim, secret);
    String jwt = base64Header + "." + base64Claim  + "." + signature;

hearder:

令牌的类型,即JWT和正在使用的散列算法,如HMAC SHA256或RSA。
{
“alg”: “HS256”,
“typ”: “JWT”
}
然后,这个JSON被Base64Url编码,形成JWT的第一部分。

源码为:

String header = Base64.encodeBase64URLSafeString(this.headerJson.getBytes(StandardCharsets.UTF_8));

Payload

令牌的第二部分是包含声明的Payload。声明是关于实体(通常是用户)和其他元数据。有三种类型的申明:
registered, public,private claims.

  • registered:
    这些是一组预先定义的申明,这些申明不是强制性的,但建议提供一套有用的,可互操作的申明。其中一些是: iss(发行者), exp(到期时间), sub(用户是谁), scope(这个用户可以做什么)等.
  • 公共的声明 :
    公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
  • 私有的声明 :
    私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
    然后将有效载荷Base64Url编码以形成JSON Web令牌的第二部分。

源码为:

String payload = Base64.encodeBase64URLSafeString(this.payloadJson.getBytes(StandardCharsets.UTF_8));

请注意,对于已签名的令牌,此信息尽管受到篡改保护,但任何人都可以阅读。除非加密,否则不要将秘密信息放在JWT的有效内容或标题元素中。
Signature
base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

##干货
###如何存储token,前后端如何用token进行“交流”
1.html5存储:localStorage or sessionStorage (Web Storage)

1.后端将token通过response返回,像这样:
HTTP/1.1 200 OK { "token": "eyJhbGciOiJIUzI1NiIsI.eyJpc3MiOiJodHRwczotcGxlL.mFrs3Zo8eaSNcxiNfvRh9dqKP4F1cB", "expires_in":3600 }
2.然后前端存储,像这样:
function tokenSuccess(err, response) { if(err){ throw err; } $window.sessionStorage.accessToken = response.body.token; }
3.请求api时,将访问令牌传回给受保护的API ( 我们需要使用HTTP Authorization 头和Bearer 模式):
HTTP/1.1 GET /****/**** Host: *****.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsI.eyJpc3MiOiJodHRwczotcGxlL.mFrs3Zo8eaSNcxiNfvRh9dqKP4F1cB

2.放置cookies中

1.后端通过response 的 Set-Cookie传回token
HTTP/1.1 200 OK Set-Cookie: access_token=eyJhbGciOiJIUzI1NiIsI.eyJpc3MiOiJodHRwczotcGxlL.mFrs3Zo8eaSNcxiNfvRh9dqKP4F1cB; Secure; HttpOnly;
2.做请求时,浏览器会自动包含cookie值

两种方式比较:
相同点:都是无状态的,因为api所需要的验证信息都在token中
不同点:
1.前者可使用跨站点脚本(XSS)进行攻击,cross-site scripting (XSS) attacks。所以,Web存储在传输过程中不执行任何安全标准。
2.Cookie与HttpOnly cookie标志一起使用时,不能通过JavaScript访问

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值