ssm 使用token校验登录的实现

背景

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。
当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。
简单token的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)

使用场景

  • token 还能起到反爬虫的作用,当然爬虫也是有突破的方法的,尽管如此还是能减少一部分爬虫访问服务器的所带来的负载。相对的爬虫技术门槛变高了。
  • 使用session也能达到用户验证的目的 、但是session 是消耗服务器的内存,在对性能要求较高的项目中 ,开发中该技术相较于token已经过时

补充

  • token主要使用于在广大的安卓开发中
  • 使用springmvc 中拦截器实现

使用方法

在maven ssm项目中pom.xml 配置 中引用jar包

		<!--token生成-->
		<dependency>
		    <groupId>com.auth0</groupId>
		    <artifactId>java-jwt</artifactId>
		    <version>3.3.0</version>
		</dependency>

创建JwtUtil 工具类

package xyz.amewin.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Java web token 工具类
 *
 * @author qiaokun
 * @date 2018/08/10
 */
public class JwtUtil {
    /**
     * 过期时间一天,
     * TODO 正式运行时修改为15分钟
     */
    private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000;
    /**
     * token私钥
     */
    private static final String TOKEN_SECRET = "f26e587c28064d0e855e72c0a6a0e618";

    /**
     * 校验token是否正确
     *
     * @param token 密钥
     * @return 是否正确
     */
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("loginName").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取登陆用户ID
     * @param token
     * @return
     */
    public static String getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名,15min后过期
     *
     * @param username 用户名
     * @return 加密的token
     */
    public static String sign(String username,String userId) {
        try {
//            过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
//            私钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
//            设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            // 附带username,userId信息,生成签名
            return JWT.create()
                    .withHeader(header)
                    .withClaim("loginName", username)
                    .withClaim("userId",userId)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

}

创建TokenInterceptor 拦截器

package xyz.amewin.interceptor;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import xyz.amewin.util.ApiResponse;
import xyz.amewin.util.Contant;
import xyz.amewin.util.JwtUtil;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Amewin
 * @date 2020/4/17 22:42
 * 此处拦截器
 */
public class TokenInterceptor implements HandlerInterceptor {

    /**
     * 拦截器和过滤器的区别
     * 1.拦截器针对访问控制器进行拦截
     * 及 @RequestMapping(value = {"/test"})
     * 简而言说就是访问方法的url
     * 应用:可以作为权限的判断,
     * 2.过滤器则是针对全局的请求
     * 包括:css/js/html/jpg/png/git/...
     * 及静态文件
     * 20200417 23:13
     */

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行方法之前执行这步操作!");
        response.setCharacterEncoding("utf-8");

        Cookie cookie=getCookieByName(request,"_COOKIE_NAME");
        //如果已经登录,不拦截
        if (null != cookie) {
            //验证token是否正确
            boolean result = JwtUtil.verify(cookie.getValue());
            if (!result) {
                return false;
            }
            return true;
        }
        //如果没有登录,则跳转到登录界面
        else {
            //重定向 第一种 调用控制器 方法
            response.sendRedirect(request.getContextPath() + "/login");
            //重定向 第二种 重定向方法
			//            request.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(request, response);
			//            System.out.println(request.getContextPath());
            return false;
            /**
             * 以下是为了登录成功后返回到刚刚的操作,不跳到主界面
             * 实现:通过将请求URL保存到session的beforePath中,然后在登录时判断beforePath是否为空
             */
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    /**
     * 根据名字获取cookie
     *
     * @param request
     * @param name    cookie名字
     * @return
     */
    public static Cookie getCookieByName(HttpServletRequest request, String name) {
        Map<String, Cookie> cookieMap = ReadCookieMap(request);
        if (cookieMap.containsKey(name)) {
            Cookie cookie =  cookieMap.get(name);
            return cookie;
        } else {
            return null;
        }
    }
    /**
     * 将cookie封装到Map里面
     *
     * @param request
     * @return
     */
    private static Map<String, Cookie> ReadCookieMap(HttpServletRequest request) {
        Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                cookieMap.put(cookie.getName(), cookie);
            }
        }
        return cookieMap;
    }

    /**
     * 返回信息给客户端
     *
     * @param response
     * @param out
     * @param apiResponse
     */
    private void responseMessage(HttpServletRequest request, HttpServletResponse response, PrintWriter out, ApiResponse apiResponse) throws IOException {
        response.setContentType("application/json; charset=utf-8");
        out.print(JSONObject.toJSONString(apiResponse));
        out.flush();
        out.close();
    }
}

spring-mvc.xml配置拦截器:

			<!--自定义拦截器-->
            <mvc:interceptors>
                <!--		验证是否登录 通过cookie -->
                <mvc:interceptor>
                    <!-- 拦截所有mvc控制器 -->
                    <mvc:mapping path="/**"/>
        			<mvc:exclude-mapping path="/checkLogin"/>
                    <bean class="xyz.amewin.interceptor.TokenInterceptor"></bean>
                </mvc:interceptor>

            </mvc:interceptors>

在控制器中使用

				//查询数据库,登录
 				PwUser pwUser = loginService.jsonLogin(username, password);
                if (pwUser != null) {
                    json.setSuccess(true);
                    json.setMsg("登录成功!");
                    String token = JwtUtil.sign(pwUser.getUsernuber(), pwUser.getUserid().toString());
                    if (token != null) {
                        Cookie cookie = new Cookie("_COOKIE_NAME", token);
                        cookie.setMaxAge(3600);//设置token有效时间
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }else{
                    json.setMsg("密码或账号错误!");
					}
                } else {
                    json.setMsg("密码或账号错误!");

                }

最后一点要web.xml 中配置加载spring-mvc拦截器

    <!-- 3.Servlet 前端控制器 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
<!--            路径-->
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
<!--        自动加载-->
        <load-on-startup>1</load-on-startup>
        <!-- <async-supported>true</async-supported> -->
    </servlet>

到此这篇关于ssm 使用token校验登录的实现的文章就介绍到这了,更多相关ssm token校验登录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ssm项目实现用户登陆持久化(token)

    用户登录持久化就是每次访问不用账号密码来校验身份,在用户登录第一次之后会返回一个token字符串,之后的访问客户端将这个token加到请求体里发给服务器就可以验证身份了. 利用Jedis和JWT创建用户token 1.JWT创建token maven依赖: <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.3.0

  • ssm 使用token校验登录的实现

    背景 token的意思是"令牌",是服务端生成的一串字符串,作为客户端进行请求的一个标识. 当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码. 简单token的组成:uid(用户唯一的身份标识).time(当前时间的时间戳).sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串.为防止token泄露) 使用场景 token 还能起到反爬虫的作用,当然爬虫也是有突破

  • SpringBoot框架集成token实现登录校验功能

    简介 公司新项目,需要做移动端(Android和IOS),登录模块,两个移动端人员提出用token来校验登录状态,一脸懵懵的,没做过,对于token的基本定义都模棱两可,然后查资料查查查,最终OK完成,写篇博客记录一下 思路: 1.基于session登录 基于session的登录(有回话状态),用户携带账号密码发送请求向服务器,服务器进行判断,成功后将用户信息放入session,用户发送请求判断session中是否有用户信息,有的话放行,没有的话进行拦截,但是考虑到时App产品,牵扯到要判断用户

  • SSM框架下实现登录注册的示例代码

    基本配置:jdk1.8   tomcat 8  MyEclipse 先打好地基: spring配置文件 application.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-

  • 浅谈nuxtjs校验登录中间件和混入(mixin)

    middleware - authLogin.js export default function ({ route, store, redirect, app, req, res }) { // store.state.auth.loggedIn 是否登录 // 权限页面检查登录状态 if (!store.state.auth.loggedIn) { store.commit('changeShowType', 'login'); // 展示登录框或者可以跳转登录页 const query =

  • SpringBoot自定义注解实现Token校验的方法

    1.定义Token的注解,需要Token校验的接口,方法上加上此注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementTyp

  • Vue项目中token验证登录(前端部分)

    本文实例为大家分享了Vue项目中token验证登录的具体代码,供大家参考,具体内容如下 1.前言 最近在做毕业设计,我是做后端的,前端并不是很懂,看vue这个框架看了近两个礼拜才有点入门的感觉,所以这篇文章写的可能不怎么好,仅作记录,有什么不对或不足的地方欢迎大神指出. 2.问题 做一个登录界面,我选择的是用token进行验证登录,我用的前端框架是Vue.js 和 element-ui,如何在vue 中使用token进行验证登录 3.思考 1.利用token进行验证登录,用户进行登录操作时,后台

  • python+pytest接口自动化之token关联登录的实现

    目录 一. 什么是token 二. token场景处理 这里介绍如下两种处理思路. 1. 思路一 2. 思路二 三. 总结 在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录. 这其实就是状态或会话保持的第三种方式token. 一. 什么是token token 由服务端产生,是客户端用于请求的身份令牌.第一次登录成功时,服务端会生成一个

  • SpringBoot整合token实现登录认证的示例代码

    1.pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</group

  • 使用SpringSecurity 进行自定义Token校验

    背景 Spring Security默认使用「用户名/密码」的方式进行登陆校验,并通过cookie的方式存留登陆信息.在一些定制化场景,比如希望单独使用token串进行部分页面的访问权限控制时,默认方案无法支持. 在未能在网上搜索出相关实践的情况下,通过官方文档及个别Stack Overflow的零散案例,形成整体思路并实践测试通过,本文即关于该方案的一个分享. 参考官方文档 SpringSecurity校验流程 基本的SpringSecurity使用方式网上很多,不是本文关注的重点. 关于校验

  • SpringBoot集成JWT生成token及校验方法过程解析

    GitHub源码地址:https://github.com/zeng-xian-guo/springboot_jwt_token.git 封装JTW生成token和校验方法 public class JwtTokenUtil { //公用密钥-保存在服务端,客户端是不会知道密钥的,以防被攻击 public static String SECRET = "ThisIsASecret"; //生成Troke public static String createToken(String u

随机推荐