第二篇-感受一下前后端分离

1.前言

在用户第一次登录成功后,服务端返回一个token回来,这个token是根据userId进行加密的,密钥只有服务器知道,然后浏览器每次请求都把这个token放在Header里请求,这样服务器只需进行简单的解密就知道是哪个用户了。
源码下载:https://download.csdn.net/download/m0_37499059/10627766


2.涉及的技术

1.springboot
2.跨域访问(CORS)和token校验
3.jjwt生成token
4.拦截器的使用
5.全局异常处理
6.postman工具使用


3.效果展示

这里写图片描述

这里写图片描述
这里写图片描述


4.核心代码解释

1.token生成的jar包

<!-- JJWT -->
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
   <version>0.9.1</version>
</dependency>

2.跨域访问公开url
使用全局的通过注解实现的方式:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //允许全部请求跨域
        registry.addMapping("/**");
    }

@Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加拦截器
        registry.addInterceptor(new JwtInterceptor()).excludePathPatterns("/user/login");
    }
}

3.Token工具类

package com.jimo.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.ServletException;
import java.util.Date;
public class JwtUtil {
    /**
     * 私钥
     */
    final static String base64EncodedSecretKey = "base64EncodedSecretKey";
    /**
     * 过期时间,测试使用60秒
     */
    final static long TOKEN_EXP = 1000 * 60;

    public static String getToken(String userName) {
        return Jwts.builder()
                .setSubject(userName)
                .claim("roles", "user")
                .setIssuedAt(new Date())
                /*过期时间*/
                .setExpiration(new Date(System.currentTimeMillis() + TOKEN_EXP))
                .signWith(SignatureAlgorithm.HS256, base64EncodedSecretKey)
                .compact();
    }

    /**
     * @func 检查token, 只要不正确就会抛出异常
     * @author jimo
     * @date 17-12-12 下午6:21
     */
    static void checkToken(String token) throws ServletException {
        try {
            final Claims claims = Jwts.parser().setSigningKey(base64EncodedSecretKey).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e1) {
            throw new ServletException("token过期!");
        } catch (Exception e) {
            throw new ServletException("other token exception");
        }
    }
}

4.拦截器

package com.jimo.security;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @func 拦截token并验证,不通过则抛出异常
 */
public class JwtInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null) {
            throw new ServletException("授权失败!");
        }
        try {
            JwtUtil.checkToken(authHeader);
            return true;
        } catch (Exception e) {
            throw new ServletException(e.getMessage());
        }
    }
}

5.Controller

package com.jimo.controller;

import com.jimo.model.User;
import com.jimo.model.common.Result;
import com.jimo.security.JwtUtil;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;

@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/login")
    public Result login(@RequestBody User user) throws Exception {
        if (!"admin".equals(user.getUsername())) {
            throw new Exception("该用户不存在!");
        }
        if (!"123456".equals(user.getPassword())) {
            throw new Exception("密码错误!");
        }
        return new Result(JwtUtil.getToken(user.getUsername()));
    }

    @GetMapping("/success")
    public Result success() {
        return new Result("login success");
    }
}

6.全局异常处理

package com.jimo.exp;

import com.jimo.model.common.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @func 全局异常处理
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e)
    {
        return new Result(false, e.getMessage());
    }
}

OK,到这里就结束了。后面会拿一个实战项目给大家看,期待ing.

猜你喜欢

转载自blog.csdn.net/m0_37499059/article/details/82082825