上次写了用户注册接口的实现,接着写登录接口
传统的登录验证方式是 session + cookie 的形式,这种验证方式不太适用于只提供 restful api 的后端系统,所以选择了 基于 token 的验证方式。
token 是个长字符串,客户端向服务器申请。在需要登录的请求中每次都携带上申请到的token,服务器端验证 token 的有效性,只有验证通过了才允许访问。具体怎么验证 token 下次再写,先来看看怎么生成 token。
我使用了JWT 形式的 token, 关于 JWT(JSON Web Token),可以看看下面两篇文章
对比上次的目录结构,多了 AuthenticationApi.java 和 AuthenticationService.java 两个文件
添加 JWT 依赖
jwt 的 java 实现由很多,经过对比,选择了下面这个。 在 pom.xml 中添加
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.0.2</version>
</dependency>
Controller 层
新建 AuthenticationApi.java 文件
@RestController
@RequestMapping("/api/authentication")
public class AuthenticationApi {
private AuthenticationService authenticationService;
private UserService userService;
@Autowired
public AuthenticationApi(AuthenticationService authenticationService, UserService userService) {
this.authenticationService = authenticationService;
this.userService = userService;
}
@PostMapping("")
public Object login(@RequestBody User user) {
User userInDataBase = userService.findByName(user.getName());
JSONObject jsonObject = new JSONObject();
if (userInDataBase == null) {
jsonObject.put("message", "用户不存在");
} else if (!userService.comparePassword(user, userInDataBase)) {
jsonObject.put("message", "密码不正确");
} else {
String token = authenticationService.getToken(userInDataBase);
jsonObject.put("token", token);
jsonObject.put("user", userInDataBase);
}
return jsonObject;
}
}
Service 层
新建 AuthenticationService.java
@Service
public class AuthenticationService {
public String getToken(User user) {
String token = "";
try {
token = JWT.create()
.withAudience(user.getId().toString()) // 将 user id 保存到 token 里面
.sign(Algorithm.HMAC256(user.getPassword())); // 以 password 作为 token 的密钥
} catch (UnsupportedEncodingException ignore) {
}
return token;
}
}
添加 comparePassword 方法
编辑 UserService.java,添加
public boolean comparePassword(User user, User userInDataBase) {
return passwordToHash(user.getPassword()) // 将用户提交的密码转换为 hash
.equals(userInDataBase.getPassword()); // 数据库中的 password 已经是 hash,不用转换
}
测试
为了方便,使用 postman 这个程序来测试。
-
先添加一个用户
从返回的 Body 那里,可以看到创建用户成功。
-
正常登陆
-
用户不存在时
-
密码错误时
查看项目完整代码
项目地址: https://github.com/hyrijk/spring-boot-blog
克隆项目到本地
git clone https://github.com/hyrijk/spring-boot-blog.git
checkout 到当前版本
git checkout 201c830d765d00014394563169b21bc1eb6c2a37
完。