前端Vue后端JavaWeb实现token简单登录校验

工作室项目里面需要实现登录校验,因为打算做的app,现在没学安卓,暂时用的vue做了个H5版的,所以用的是token进行登录校验,没有使用传统的cookie session

时间:2021-1-20

一、技术要点

前端:
1.Axios及拦截器
2.vue路由
后端:
1.token的使用(用的是jwt)
2.servlet及过滤器

二、流程

  1. 前端登录发送axios请求,
  2. 后端接收数据后核验,如果正确返回生成的token和用户的基本信息,否则返回401
  3. 前端接收token后存储在localstorage中,在之后的每一次请求中给请求头添加token
  4. 后端使用过滤器,对每一个请求检查token,正确则放行,不存在或错误则返回401

三、具体代码

1.axios发送登录请求

login.vue

前端登录代码
this.$qs.stringify(data) 将参数序列化成URL的形式,从而可以发送formData类型的数据
axios默认以play load的类型发送参数,

export default {
    data(){
        return {
        user:{
            userPhone:"",
            userPassward:""
            }
        }
    },
    methods:{
        login:function(){
            let data = {P
                userPhone:this.user.userPhone,
                userPassword:this.user.userPassward               
            };
            this.$axios.post('http://localhost/login',this.$qs.stringify(data))
            .then((res)=>{
                if(res.status == 200){
                    //将token和用户的基本信息存储在localStorage
                    localStorage.setItem("user",JSON.stringify(res.data));
                    localStorage.setItem("authorization",res.headers.authorization);
                    //跳转首页
                    this.$router.push('/index');
                }
            })
            .catch((err)=>{
                alert("账号或密码错误!");
                console.log(err);
            })
        }
    }
}

2.使用拦截器对每一个请求的请求头加上token

main.js

在main.js中配置axios拦截器,给每个请求的请求头加上token
不懂的可以搜axios拦截器

import axios from 'axios' 
Vue.prototype.$axios = axios

axios.interceptors.request.use(
  config=>{
    const authorization = localStorage.getItem('authorization')
    console.log('axios拦截器拦截请求');
    if (authorization) {
      config.headers.authorization = authorization
    }
    return config
  },
  err =>{
    console.log('err:'+err);
    return Promise.reject(err)
  }
)

3. 在前端校验是否登录

index.js

在router的index.js中给每一个路由配置beforeEach,在每一个路由跳转前判断是否登录,未登录返回登录界面,
关于此知识点可以搜索vue路由钩子函数

const router =  new Router({
	routes:[
		......
	]
})

router.beforeEach(
  (to,from,next)=>{
    let authorization = localStorage.getItem('authorization');
    if(authorization){//是否存在token
      if(to.name == 'login'){
        console.log("已登录,跳转首页!");
        next('/index')
      }else {
        next();
      }
    }else {
      if(to.name == 'login'){
        next();
      }else {
        console.log("未登录,跳转登录页!");
        next('/');
      }
    }
  }
)

export default router

4.后端登录请求

LoginServlet.java

变量下划线就不要管了,不规范,数据库用的下划线,工具栏生成的忘记改了,注意一下

Gson转成json输出时是字符串,等axios接收后不知道为什么是对象了,所以前端用JSON.stringify又转了一遍.,按道理response.getWriter().write()不会自动将json字符串转成对象,print()会,之前用Ajax可以返回字符串,希望知道的大佬告知一声,谢谢!

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从前端表单获取的账号密码
        String user_phone = request.getParameter("user_phone");
        String user_password =  request.getParameter("user_password");
        System.out.println("手机号:"+user_phone+"密码:"+user_password);
        //调用业务层代码进行登录
        UserService userService = new UserServiceImpl();
        User user = userService.login(user_phone,user_password);
        if(user==null){
            response.setStatus(401);
        }else {//向前端回传
            String token = TokenUtils.token(user.getUser_phone());
            User localUser = new User(user.getUser_id(),user.getUser_name(),user.getUser_phone(),user.getUser_realname(),user.getUser_school());
            Gson gson = new Gson();
            String json = gson.toJson(localUser);
            response.setHeader("Authorization",token);
            System.out.println("用户:"+json);
            response.getWriter().write(json);
        }
    }

6.后端过滤器,对前端每一个请求进行过滤

LoginFilter.java

过滤器,对前端传来的请求过滤,

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request=(HttpServletRequest) req;
        HttpServletResponse response=(HttpServletResponse) resp;
        //获取请求资源路径
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
        //3.判断是否包含登录相关资源路径
        if ( requestURI.contains("login") ) {
            System.out.println("这是登录界面,放行");
            chain.doFilter(req, resp);
        } else {
            //4.判断是否有token
            String authorization= request.getHeader("authorization");
            if(authorization!=null){
                boolean verify = TokenUtils.verify(authorization);
                if(verify){
                    chain.doFilter(req, resp);
                    System.out.println("token有效,放行");
                }else {
                    response.setStatus(401);
                    System.out.println("token无效,401");
                }
            }else {
                System.out.println("token不存在,401");
                response.setStatus(401);
            }
        }
    }

四、结语

  1. 不用axios直接用Ajax,我还不知道怎么处理给每个请求头加上token,在网上没有找到合适的方法,难道真的只能复制粘贴给每个请求加上token吗?
  2. Gson转成json输出时是字符串,等axios接收后不知道为什么是对象了,所以前端用JSON.stringify又转了一遍.,按道理response.getWriter().write()不会自动将json字符串转成对象,print()会,之前用Ajax可以返回字符串,希望知道的大佬告知一声,谢谢!

本人实力有限,如有错误或更好的建议,还望各位不吝赐教

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端Vue传递加密密文到后端Java,后解密的示例代码如下: 前端Vue加密代码: ```javascript // 导入jsencrypt库 import JSEncrypt from 'jsencrypt' // 创建RSA加密实例 const encrypt = new JSEncrypt() // 设置RSA公钥 const publicKey = 'YOUR_RSA_PUBLIC_KEY' encrypt.setPublicKey(publicKey) // 要加密的数据 const data = 'YOUR_DATA_TO_ENCRYPT' // 使用RSA公钥进行加密 const encryptedData = encrypt.encrypt(data) // 将加密后的数据发送到后端 // 例如使用axios发送POST请求 axios.post('/api/decrypt', { encryptedData }) .then(response => { console.log(response.data) }) .catch(error => { console.error(error) }) ``` 后端Java解密代码: ```java import org.apache.commons.codec.binary.Base64; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; @RestController public class DecryptionController { // 将Base64编码后的私钥字符串转换为PrivateKey对象 private PrivateKey getPrivateKey(String privateKeyStr) throws Exception { byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(keySpec); } @PostMapping("/api/decrypt") public String decryptData(@RequestBody EncryptedData encryptedData) throws Exception { String privateKeyStr = "YOUR_RSA_PRIVATE_KEY"; PrivateKey privateKey = getPrivateKey(privateKeyStr); // 使用私钥进行解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] encryptedBytes = Base64.decodeBase64(encryptedData.getEncryptedData()); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); // 返回解密后的数据 return new String(decryptedBytes, StandardCharsets.UTF_8); } } ``` 创建一个名为 `EncryptedData` 的Java类,用于接收前端传递的加密数据: ```java public class EncryptedData { private String encryptedData; public String getEncryptedData() { return encryptedData; } public void setEncryptedData(String encryptedData) { this.encryptedData = encryptedData; } } ``` 请将 `YOUR_RSA_PUBLIC_KEY` 替换为你的RSA公钥,将 `YOUR_RSA_PRIVATE_KEY` 替换为你的RSA私钥。在前端,你可以使用axios或其他HTTP库发送POST请求到后端的 `/api/decrypt` 路径,并将加密后的数据作为请求体的 `encryptedData` 字段传递。后端将解密后的数据作为响应返回给前端

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值