1.导包 在pom.xml中导入需要的依赖jar包,点击刷新下载 - <dependency>
- <groupId>com.auth0</groupId>
- <artifactId>java-jwt</artifactId>
- <version>3.10.0</version>
- </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
一般一个设置为账号,一个设置为密码 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文件夹下面找找)
其中<mvc:mapping path=“/admin/**”/>代表要拦截的地址,我的所有方法都在admin下面,admin是controller层下面的文件夹。
<mvc:exclude-mapping path=“/admin/checkLogin”/>代表不需要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";
- }
复制代码
|