需要提供两个接口,用户认证接口和访问前检验token接口。

流程:

  • 用户传入username和password(以“zhangsan" "123456"为例),拿着这两个信息去查数据库作认证。若认证通过,基于想要的用户信息生成一个token,然后把token响应给用户。
  • 日后用户在请求其他接口的时候,用户都要携带着token请求。若携带的token验证通过,则服务器允许访问;若验证不通过,则服务器拒绝访问。

一、配置pom.xml

<!-- jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.4.0</version>
</dependency>

二、配置application.properties文件

配置数据库和mybatis

三、建立数据库和数据库中的表

表结构:

spring boot jwt 刷新 springboot+jwt_客户端

表中数据:

spring boot jwt 刷新 springboot+jwt_数据库_02

四、实体

包:entity

实体类:UserAdmin

@TableName("user")
public class UserAdmin {
    private String id;
    private String name;
    private String password;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
}

五、DAO接口和mapper.xml

包:java下面的mapper

DAO接口:UserAdminMapper

@Mapper
public interface UserAdminMapper{
    UserAdmin login(UserAdmin userAdmin);
}

包:resources下面的mapper 

UserAdminMapper.xml文件

<mapper namespace="com.xxx.gamejump.mapper.UserAdminMapper">
    <select id="login" parameterType="UserAdmin" resultType="UserAdmin">
        select * from g_admin where name =#{name} and password =#{password}
    </select>
</mapper>

六、Service接口以及实现类

@Service
public interface UserAdminService {
    /*
        管理员登录接口
     */
    UserAdmin login(UserAdmin userAdmin);
}
@Service
@Transactional
public class UserAdminServiceImpl implements UserAdminService{

    @Autowired
    private UserAdminMapper userAdminMapper;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public UserAdmin login(UserAdmin userAdmin) {
        //根据接收的用户名和密码查询数据库
        UserAdmin admin = userAdminMapper.login(userAdmin);
        if(admin != null){
            return admin;
        }
        throw new RuntimeException("登陆失败--");
    }
}

七、Controller类

UserAdminController类

login方法:验证用户名密码,生成token令牌

@RestController
@RequestMapping("/admin")
@CrossOrigin(origins = "*")
public class UserAdminController {
    private Logger logger = LoggerFactory.getLogger(UserAdminController.class);

    @Autowired
    private UserAdminService userAdminService;

    @GetMapping("/login")
    public Map<String,Object> login(UserAdmin userAdmin){
        logger.info("用户名:[{}]",userAdmin.getName());
        logger.info("密码:[{}]",userAdmin.getPassword());
        Map<String,Object> map = new HashMap<>();
        try{
            UserAdmin useradminDB = userAdminService.login(userAdmin);
            Map<String,String> payload = new HashMap<>();
            payload.put("id",useradminDB.getId());
            payload.put("name",useradminDB.getName());
            //生成JWT令牌
            String token = JWTUtils.getToken(payload);
            map.put("state",true);
            map.put("msg","认证成功");
            map.put("token",token);//响应token
        }catch(Exception e){
            map.put("state",false);
            map.put("msg",e.getMessage());
        }

        return map;
    }

 首先运行程序,然后用Postman工具测试login方法。

 测试1:认证成功示例

GET方式访问:http://localhost:8089/admin/login?name=lrq&password=12345

传参:

name:lrq

password:12345

spring boot jwt 刷新 springboot+jwt_jwt_03

因为数据库表中有一行为这组数据,所以成功查询数据库表,用户名密码验证成功。

服务器响应如下:

服务器端:

spring boot jwt 刷新 springboot+jwt_数据库_04

postman客户端:

spring boot jwt 刷新 springboot+jwt_jwt_05

测试2:认证失败示例

GET方式访问:http://localhost:8089/admin/login?name=xiaoming&password=12345

传参:

name:xiaoming

password:12345

spring boot jwt 刷新 springboot+jwt_数据库_06

数据库中没有xiaoming这行数据,用户名密码验证失败。

服务器响应如下:

服务器端:

spring boot jwt 刷新 springboot+jwt_服务器端_07

postman客户端:

spring boot jwt 刷新 springboot+jwt_客户端_08

 test方法:进入任意接口之前都要进行的jwt检验方法

@PostMapping("/test")
    public Map<String,Object> test(String token) {
        Map<String, Object> map = new HashMap<>();
        logger.info("当前token为:[{}]", token);
        //System.out.println("当前token为");
        try {
            DecodedJWT verify = JWTUtils.verify(token); //验证令牌
            map.put("state",true);
            map.put("msg","请求成功!");
            return map;
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            map.put("msg","无效签名!");
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            map.put("msg","token过期!");
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            map.put("msg","算法不一致!");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg","token无效!");
        }
        map.put("state",false);
        return map;
    }

测试1:不传入token

spring boot jwt 刷新 springboot+jwt_服务器端_09

服务器端:

spring boot jwt 刷新 springboot+jwt_jwt_10

postman客户端:

spring boot jwt 刷新 springboot+jwt_spring boot jwt 刷新_11

测试2: 传入合法token

spring boot jwt 刷新 springboot+jwt_jwt_12

Postman客户端: 

spring boot jwt 刷新 springboot+jwt_服务器端_13

服务器端: 

spring boot jwt 刷新 springboot+jwt_服务器端_14

注:POST方式请求时的token传参,官方不建议在url中以参数形式传递token,建议将token隐藏放置在请求头里面。

测试3:token过期

spring boot jwt 刷新 springboot+jwt_数据库_15

Postman客户端: 

spring boot jwt 刷新 springboot+jwt_服务器端_16

服务器端:

spring boot jwt 刷新 springboot+jwt_服务器端_17