Springboot+vuje使用jwt实现登录验证之发送请求

关于作者
金山老师:从事Java、大数据、Python职业化培训6年,项目管理、软件开发14年。欢迎添加我的微信号【jshand】,最近建了一些微信交流群,扫描下方二维码添加公众号,回复:进群

在这里插入图片描述

登录的逻辑

传统jsp

在这里插入图片描述

vuejs

基于cookie
在这里插入图片描述

axios中携带cookie处理起来比较麻烦,

在这里插入图片描述

可以使用jwt,登录之后将登录的信息,记录到h5的缓存中(自己操作),每次请求从本地存储控件取出来,可以使用jwt进行验证。
在这里插入图片描述

jwt

什么是JWT?

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

Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *
在这里插入图片描述

实现jwt验证用户身份

使用生成Token

  • 添加依赖
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.1</version>
</dependency>

  • 单元测试测试生成Token, 和验证Token
package com.neuedu.boot.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.junit.jupiter.api.Test;

public class JWTTest {

    /**
     * 模拟的是登录的 生成jwt json
     */
    @Test
    public void testCreate(){
        String secret = "abcdef";
        String jwtString = JWT.create().
                withClaim("username", "root").  //设置登录的信息
                sign(Algorithm.HMAC256(secret));
        // admin
        // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.AwXJiXuMoJodNCq3EslfV6wVrwLIFFcaFqsAsWfITQg

        // root
        // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InJvb3QifQ.c8kyOTkxOll2LM2_cEJpV2m1VtxSkkGyGET9F1WfqVE
        System.out.println(jwtString);


    }



    @Test
    public void decode(){
        //admin
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.AwXJiXuMoJodNCq3EslfV6wVrwLIFFcaFqsAsWfITQg";
        DecodedJWT decode = JWT.decode(token);
        String username = decode.getClaim("username").asString();
        System.out.println("username = " + username);



        //root
        token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InJvb3QifQ.c8kyOTkxOll2LM2_cEJpV2m1VtxSkkGyGET9F1WfqVE";
        decode = JWT.decode(token);
        username = decode.getClaim("username").asString();
        System.out.println("username = " + username);
    }


}

在用户登录中使用Token

controller

package com.neuedu.boot.controller;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.neuedu.boot.config.CommonResult;
import com.neuedu.boot.entity.User;
import com.neuedu.boot.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

    @Autowired
    IUserService userService;

    @RequestMapping("/login")
    CommonResult login(User user){

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("username",user.getUsername());
        queryWrapper.eq("password",user.getPassword());

        User one = userService.getOne(queryWrapper);
        if(one!= null){
            //使用用户身份生成jwt token ,发送个浏览器
            String secret = "abcdef";
            String token = JWT.create().
                    withClaim("userId", one.getUserId()).  //设置登录用户id
                    withClaim("username", one.getUsername()).  //设置登录的用户名
                    sign(Algorithm.HMAC256(secret));
            return CommonResult.success(token);
        }else{
            return CommonResult.failed("登录失败");
        }

    }


}

vuejs

<template>
	<div>
		用户名:<input type="text" v-model="loginForm.username"/> <br/>
		密码<input type="password" v-model="loginForm.password"/> <br/>
		<button @click="login()">登录</button>
		
	</div>
</template>

<script>
	export default {
		name:'Login',
		data(){
			return {
				loginForm:{
					username:'',
					password:''
				}
			}
		},
		methods:{
			//登录验证
			login(){
				let url = '/api/login';
				this.http.get(url, (token) => {
					console.log("token:",token);
					alert("token:"+token)
				}, this.loginForm)
			}
		}
	}
</script>

<style>
</style>

单独的引入elementUI的组件

import { Message } from 'element-ui';
// alert("出错了:"+message)
Message.error({
	message:message,
	duration:2000,
	offset:200
})
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

金山老师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值