spring boot、mybatis 实现用户登录接口

上次写了用户注册接口的实现,接着写登录接口

传统的登录验证方式是 session + cookie 的形式,这种验证方式不太适用于只提供 restful api 的后端系统,所以选择了 基于 token 的验证方式。

token 是个长字符串,客户端向服务器申请。在需要登录的请求中每次都携带上申请到的token,服务器端验证 token 的有效性,只有验证通过了才允许访问。具体怎么验证 token 下次再写,先来看看怎么生成 token。

我使用了JWT 形式的 token, 关于 JWT(JSON Web Token),可以看看下面两篇文章

  1. JSON Web Token - 在Web应用间安全地传递信息
  2. 八幅漫画理解使用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

完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,890评论 18 139
  • 构建用户管理微服务翻译自:https://springuni.com 构建用户管理微服务(一):定义领域模型和 R...
    极乐君阅读 1,570评论 0 10
  • 在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用...
    安琪拉_4b7e阅读 1,762评论 2 7
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,947评论 6 342
  • 今天听的课叫做爱与规则。 爱孩子,我一直觉得再容易不过的。爱,之于呼吸;那是生命跳动的力量。可是如何去爱,如何让爱...
    萌奶糖阅读 811评论 0 2