SSM框架配置使用token与测试使用(极其详细)

SSM框架配置使用token --毕设遇见的问题2

token在现在用的特别多,但网上基本上都是在springboot框架中配置。这里记录一下SSM框架中配置

1.导包

在pom.xml中导入需要的依赖jar包,点击刷新下载

 		<dependency>
            <groupId>com.auth0groupId>
            <artifactId>java-jwtartifactId>
            <version>3.10.0version>
        dependency>

2.编写token的代码

一般来说,在项目的文件夹下创建一个文件夹utils,在下面创建一个java文件JWTUtils。

2个变量

private static final long EXPIRE_TIME = 15 * 60 * 1000;//代表过期时间(15分钟),前端这么长时间没操作,就过期了,需要重新登录。
private static final String TOKEN_SECRET = “f26e587c28064d0e855e72c0a6a0e618”;//代表密钥,随便自己设置,越复杂越难被破解

4个方法

public static String sign(String username,String userId) //生成token,用户登录之后就调用这个方法。输入两个参数,一般是账号和密码
public static boolean verify(String token)//验证token,在每次访问接口的时候使用,一般在拦截器中使用(拦截器后面有)
public static String getUsername(String token) //通过token获取用户名
public static String getUserId(String token)//通过token获取用户id
一般一个设置为账号,一个设置为密码

import com.auth0.jwt.*;
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 工具类

 *


 */

public class JWTUtils {

    /**

     * 过期时间一天,

     * TODO 正式运行时修改为15分钟

     */

    private static final long EXPIRE_TIME =  15 * 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) {
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);// 私钥及加密算法
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        // 设置头部信息
        Map 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);
    }

}

3.编写拦截器代码

token的作用是验证用户的登录信息,前端的每次http请求都需要检测用户是否登录。因此,需要编写拦截器的代码。在项目下面创建一个文件夹 interceptor,在里面创建TokenInterceptor.java文件,放入代码。
最重要的是preHandle方法,因为我前端传过来的token的名字叫sessionValue,所以我获取的是sessionValue,如果前端传来的token名字叫token,把下面代码String token=request.getParameter(“sessionValue”);中的sessionValue改为token。
如果通过验证,就为true,进入后端controller方法,如果没有通过,返回前端false。
如果没有token值传来,就是进行页面跳转到登陆页面。

import com.alibaba.fastjson.JSONObject;
import com.lostAndFound.utils.JWTUtils;
import io.swagger.annotations.ApiResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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;

/**
 * 此处拦截器
 */
public class TokenInterceptor implements HandlerInterceptor {

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

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setCharacterEncoding("utf-8");
        String token=request.getParameter("sessionValue");
        //Cookie cookie=getCookieByName(request,"_COOKIE_NAME");
        //如果已经登录,不拦截
        if (null != token) {
            //验证token是否正确
            boolean result = JWTUtils.verify(token);
            System.out.println("是否通过拦截器:"+result);
            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();
    }

4.在配置文件中配置拦截器

token的作用是验证用户的登录信息,前端的每次http请求都需要检测用户是否登录,但是登录的时候没有token,所以需要放行token。系统不知道什么时候需要拦截,什么时候不拦截。因此需要配置需要拦截的地址。配置在spring-mvc.xml文件中。(也有可能不叫spring-mvc.xml,不过名字一般和mvc,web有关,比如spring-web,在resources文件夹下面找找)
其中代表要拦截的地址,我的所有方法都在admin下面,admin是controller层下面的文件夹。
代表不需要token验证的方法,常见是登录
告诉系统拦截的的位置(前面第三点的位置)



    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/admin/**"/>
            <mvc:exclude-mapping path="/admin/checkLogin"/>
            <bean class="com.lostAndFound.interceptor.TokenInterceptor">bean>
        mvc:interceptor>
    mvc:interceptors>

5.测试

登录的方法,前端传来账号密码,首先判断账号密码是否正确,正确创建token并返回,错误返回false
其他业务方法基本相同,因为在拦截器已经验证过token是否有效了,这里就不需要验证了。

	@RequestMapping(value = "/checkLogin")
    @ResponseBody
    public String checkLogin(@RequestParam() String username, @RequestParam() String password){

        Admin admin=new Admin();
        admin.setId(Integer.parseInt(username));
        admin.setPassword(password);
        boolean bool = adminService.checkAdminLog(admin);
        System.out.println("密码是否正确:"+bool);
        if(bool){
            //返回token值
            String token = JWTUtils.sign(username, password);
            System.out.println(token);
            return token;
        }
        else{
            return "false";
        }

你可能感兴趣的:(java,web开发,java,前端)