springboot+vue前后端分离项目中使用jwt实现登录认证

 更新时间:2024年10月09日 10:48:23   作者:登山人在路上  
本文介绍了如何在SpringBoot+Vue前后端分离的项目中使用JWT实现登录认证,内容包括后端的响应工具类、JWT工具类、登录用户实体类、登录接口、测试接口、过滤器、启动类以及前端的登录页面实现,感兴趣的可以了解一下

一、后端代码

1.响应工具类

package com.etime.util;

import com.etime.vo.ResponseModel;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Date 2024/6/10 10:00
 * @Author liukang
 **/
public class ResponseUtil {
    public static void write(ResponseModel rm, HttpServletResponse response) throws IOException {
        // 构造响应头
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("utf-8");
        // 解决跨域问题 设置跨域头
        response.setHeader("Access-Control-Allow-Origin","*");
        // 输出流
        PrintWriter out = response.getWriter();
        // 输出
        out.write(new ObjectMapper().writeValueAsString(rm));
        // 关闭流
        out.close();
    }
}

2.jwt工具类

package com.etime.util;

import io.jsonwebtoken.*;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @Date 2024/6/10 10:04
 * @Author liukang
 **/
public class JwtUtil {
    private static String secret = "secret";

    /**
     * 创建jwt
     * @author liukang
     * @date 10:36 2024/6/10
     * @param expire
     * @param map
     * @return java.lang.String
     **/
    public static String generateToken(long expire, Map map){
        // 床jwt构造器
        JwtBuilder jwtBuilder = Jwts.builder();
        // 生成jwt字符串
        String jwt = jwtBuilder
                //头部
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")
                // 载荷
                .setClaims(map) // 设置多个自定义数据  位置只能放在前面,如果放在后面,那前面的载荷会失效
                .setId(UUID.randomUUID().toString())// 唯一标识
                .setIssuer("liukang")// 签发人
                .setIssuedAt(new Date())// 签发时间
                .setSubject("jwtDemo")// 主题
                .setExpiration(new Date(System.currentTimeMillis()+expire))//过期时间
                // 签名
                .signWith(SignatureAlgorithm.HS256,secret)
                .compact();
        return jwt;
    }
    /**
     * 创建jwt
     * @author liukang
     * @date 10:36 2024/6/10
     * @param expire
     * @return java.lang.String
     **/
    public static String generateToken(long expire){
        // 床jwt构造器
        JwtBuilder jwtBuilder = Jwts.builder();
        // 生成jwt字符串
        String jwt = jwtBuilder
                //头部
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")
                // 载荷
                .setId(UUID.randomUUID().toString())// 唯一标识
                .setIssuer("liukang")// 签发人
                .setIssuedAt(new Date())// 签发时间
                .setSubject("jwtDemo")// 主题
                .setExpiration(new Date(System.currentTimeMillis()+expire))//过期时间
                // 签名
                .signWith(SignatureAlgorithm.HS256,secret)
                .compact();
        return jwt;
    }
    /**
     * 解析jwt
     * @author liukang
     * @date 10:36 2024/6/10
     * @param jwt
     * @return io.jsonwebtoken.Claims
     **/
    public static Claims parseToken(String jwt){
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt);
        Claims playload = claimsJws.getBody();
        return playload;

    }
}

3.登录用户实体类

package com.etime.entity;

import lombok.Data;

/**
 * @Date 2024/6/10 10:39
 * @Author liukang
 **/
@Data
public class User {
    private String username;
    private String password;
}

4.登录接口

package com.etime.controller;

import com.etime.entity.User;
import com.etime.util.JwtUtil;
import com.etime.vo.ResponseModel;
import org.springframework.web.bind.annotation.*;

/**
 * @Date 2024/6/10 10:38
 * @Author liukang
 **/
@RestController
@CrossOrigin
public class LoginController {
    @PostMapping("/login")
    public ResponseModel login(@RequestBody User user){
        Integer code = 200;
        String msg = "success";
        String token = null;
        if(user.getUsername().equals("admin")&&user.getPassword().equals("123")){
            // 生成jwt
            token = JwtUtil.generateToken(1000*10);// 设置有效期为10s
        }else {
            code = 500;
            msg = "failure";
        }
        return new ResponseModel(code,msg,token);
    }


}

5.测试接口

package com.etime.controller;

import com.etime.vo.ResponseModel;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Date 2024/6/10 12:51
 * @Author liukang
 **/
@CrossOrigin
@RestController
public class TestController {
    @PostMapping("/test")
    public ResponseModel test() {
        return new ResponseModel(200,"success","测试请求接口成功!");
    }

}

6.过滤器

package com.etime.filter;

import com.etime.util.JwtUtil;
import com.etime.util.ResponseUtil;
import com.etime.vo.ResponseModel;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Description jwt过滤器
 * @Date 2024/6/10 9:46
 * @Author liukang
 **/
@WebFilter(urlPatterns = "/*") // 过滤所有路径
public class JwtFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 得到两个对象
        HttpServletRequest request =  (HttpServletRequest) servletRequest;
        HttpServletResponse response =  (HttpServletResponse) servletResponse;
        //直接放行
        if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){
            filterChain.doFilter(request,response);
            return;
        }
        String requestURI = request.getRequestURI(); // 不含主机和端口号
        if(requestURI.contains("/login")){
            filterChain.doFilter(request,response);
            return;
        }
        // 得到请求头的信息(accessToken)
        String token = request.getHeader("accessToken");
        if(!StringUtils.hasText(token)){
            //响应前端错误的消息提示
            ResponseModel responseModel = new ResponseModel(500,"failure","令牌缺失!");
            ResponseUtil.write(responseModel,response);
            return;
        }
        // 解析Token信息
        try {
            JwtUtil.parseToken(token);
        }catch (Exception e){
            //响应前端错误的消息提示
            ResponseModel responseModel = new ResponseModel(401,"failure","令牌过期!");
            ResponseUtil.write(responseModel,response);
            return;
        }
        filterChain.doFilter(request,response);


    }
}

7.启动类

package com.etime;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * @Author liukang
 * @Date 2022/7/4 11:32
 */
@SpringBootApplication
@ServletComponentScan(basePackages = "com.etime.filter")// 这个包下激活WebFilter这个注解
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

二、前端代码

登录页

<template>
    <div class="hello">
      <form>
        用户名:<input v-model="username"/>
        <br>
        密码<input v-model="password" />
        <br>
        <button @click="login">登录</button>
      </form>

    </div>
  </template>

  <script>


  export default {
    data () {
      return {
        username:'',
        password:'',

      }
    },
    methods:{
        login(){
          this.axios.post('http://localhost:8088/login',{

            username:this.username,
            password:this.password,

          }).then(response => {
              console.log(response.data);
              if(response.data.code==200){
                sessionStorage.setItem("accessToken",response.data.token)
                this.$router.push({ path: 'index'});
              }
            }).catch(error => {
              console.error(error);
            });

        }
    },
  }
  </script>

  <style scoped>

  </style>

index 页面

<template>
    <div>
        <button @click="test">请求受保护的接口</button>
    </div>
  </template>

  <script>
  export default {
    data () {
      return {
      }
    },
    methods:{
      test(){
        const accessToken = sessionStorage.getItem('accessToken')
        let token = null
        if(accessToken){
          token = accessToken
        }
        console.log(token)
        this.axios.post('http://localhost:8088/test',{},{headers:{accessToken:token}
        }).then(response => {
          // if(response.data.code==200){
            console.log(response.data);
          // }
        }).catch(error => {
          console.error(error);
        });
      },
    
    },
  }
  </script>

  <style scoped>

  </style>

三、效果展示

1.点击登录后,后端给前端办法jwt令牌,前端将其存入sessionStorage中

在这里插入图片描述

2.点击【请求后端受保护的接口】按钮

在这里插入图片描述

3.继续多次点击【请求后端受保护的接口】按钮

在这里插入图片描述

可以看见,请求几次成功后,便显示令牌过期,这是因为,为了测试方便,我们颁发令牌时有效期设置的10秒

在这里插入图片描述

4.在请求接口中不传递Token

在这里插入图片描述

重新登录并点击【请求后端受保护的接口】按钮

在这里插入图片描述

到此这篇关于springboot+vue前后端分离项目中使用jwt实现登录认证的文章就介绍到这了,更多相关springboot vue jwt登录认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Flowable中定时器的玩法详解

    Flowable中定时器的玩法详解

    这篇文章主要为大家详细介绍了Flowable中定时器的各种玩法,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-11-11
  • 推荐一款IntelliJ IDEA提示快捷键的Key Promoter X插件

    推荐一款IntelliJ IDEA提示快捷键的Key Promoter X插件

    今天小编就为大家分享一篇关于IntelliJ IDEA提示快捷键的Key Promoter X插件,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • SpringBoot整合MyBatis-Plus乐观锁不生效的问题及解决方法

    SpringBoot整合MyBatis-Plus乐观锁不生效的问题及解决方法

    这篇文章主要介绍了SpringBoot整合MyBatis-Plus乐观锁不生效的问题解决方案,通过实例代码介绍了SpringBoot各个层次的操作,需要的朋友可以参考下
    2022-04-04
  • SpringBoot实现定时发送邮件的三种方法案例详解

    SpringBoot实现定时发送邮件的三种方法案例详解

    这篇文章主要介绍了SpringBoot三种方法实现定时发送邮件的案例,Spring框架的定时任务调度功能支持配置和注解两种方式Spring Boot在Spring框架的基础上实现了继承,并对其中基于注解方式的定时任务实现了非常好的支持,本文给大家详细讲解,需要的朋友可以参考下
    2023-03-03
  • 在Java中轻松将HTML格式文本转换为纯文本的方法示例(保留换行)

    在Java中轻松将HTML格式文本转换为纯文本的方法示例(保留换行)

    这篇文章主要介绍了在Java中轻松将HTML格式文本转换为纯文本的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • java 中链表的定义与使用方法

    java 中链表的定义与使用方法

    这篇文章主要介绍了java 中链表的定义与使用方法的相关资料,需要的朋友可以参考下
    2017-03-03
  • Java中Maven项目导出jar包配置的示例代码

    Java中Maven项目导出jar包配置的示例代码

    这篇文章主要介绍了Java中Maven项目导出jar包配置的示例代码,需要的朋友可以参考下
    2018-11-11
  • Java异常Exception详细讲解

    Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等
    2022-07-07
  • springboot+websocket实现并发抢红包功能

    springboot+websocket实现并发抢红包功能

    本文主要介绍了springboot+websocket实现并发抢红包功能,主要包含了4种步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Java在Linux上调用FFmpeg实现视频截图的完整指南

    Java在Linux上调用FFmpeg实现视频截图的完整指南

    在Linux环境下使用Java与FFmpeg命令交互进行视频截图是多媒体处理中的常见任务,本文介绍了如何在Java程序中执行FFmpeg命令,通过提供具体代码示例来展示在特定时间点获取视频静态图像的方法,需要的朋友可以参考下
    2025-08-08

最新评论