- 模拟 HTTP 请求工具,我使用的是 PostMan。
简要的说明下我们为什么要用 JWT ,因为我们要实现完全的前后端分离,所以不可能使用 session
, cookie
的方式进行鉴权,所以 JWT 就被派上了用场,你可以通过一个加密密钥来进行前后端的鉴权。
程序逻辑
-
我们 POST 用户名与密码到
/login
进行登入,如果成功返回一个加密 token,失败的话直接返回 401 错误。 -
之后用户访问每一个需要权限的网址请求必须在
header
中添加Authorization
字段,例如Authorization: token
,token
为密钥。 -
后台会进行
token
的校验,如果有误会直接返回 401。
Token加密说明
-
携带了
username
信息在 token 中。 -
设定了过期时间。
-
使用用户登入密码对
token
进行加密。
Token校验流程
-
获得
token
中携带的username
信息。 -
进入数据库搜索这个用户,得到他的密码。
-
使用用户的密码来检验
token
是否正确。
准备Maven文件
新建一个 Maven 工程,添加相关的 dependencies。
<?xml version="1.0" encoding="UTF-8"?><project xmlns=“http://maven.apache.org/POM/4.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
4.0.0
org.inlighting
shiro-study
1.0-SNAPSHOT
org.apache.shiro
shiro-spring
1.3.2
com.auth0
java-jwt
3.2.0
org.springframework.boot
spring-boot-starter-web
1.5.8.RELEASE
org.springframework.boot
spring-boot-maven-plugin
1.5.7.RELEASE
repackage
org.apache.maven.plugins
maven-compiler-plugin
1.81.8
UTF-8
注意指定JDK版本和编码。
构建简易的数据源
为了缩减教程的代码,我使用 HashMap
本地模拟了一个数据库,结构如下:
| username | password | role | permission |
| — | — | — | — |
| smith | smith123 | user | view |
| danny | danny123 | admin | view,edit |
这是一个最简单的用户权限表,如果想更加进一步了解,自行百度 RBAC。
之后再构建一个 UserService
来模拟数据库查询,并且把结果放到 UserBean
之中。
UserService.java
@Component
public class UserService {
public UserBean getUser(String username) {
// 没有此用户直接返回null
if (! DataSource.getData().containsKey(username))
return null;
UserBean user = new UserBean();
Map<String, String> detail = DataSource.getData().get(username);
user.setUsername(username);
user.setPassword(detail.get(“password”));
user.setRole(detail.get(“role”));
user.setPermission(detail.get(“permission”));
return user;
}
}
UserBean.java
public class UserBean {
private String username;
private String password;
private String role;
private String permission;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
retur