新增:新增用户登录和退出 API(引入 Sa-Token 依赖,详情可见 README 介绍)

This commit is contained in:
2022-12-22 19:39:27 +08:00
parent d54c93aebc
commit 00e2b44d0e
27 changed files with 1352 additions and 49 deletions

View File

@@ -33,6 +33,8 @@ import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.dev33.satoken.annotation.SaIgnore;
import top.charles7c.cnadmin.common.config.properties.ContinewAdminProperties;
/**
@@ -62,6 +64,7 @@ public class ContinewAdminApplication implements ApplicationRunner {
* @return /
*/
@Hidden
@SaIgnore
@GetMapping("/")
public String index() {
return String.format("%s backend service started successfully.", properties.getName());

View File

@@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RestController;
import com.wf.captcha.base.Captcha;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.IdUtil;
import top.charles7c.cnadmin.auth.config.properties.CaptchaProperties;
@@ -44,6 +45,7 @@ import top.charles7c.cnadmin.common.util.RedisUtils;
* @since 2022/12/11 14:00
*/
@Tag(name = "验证码 API")
@SaIgnore
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/captcha", produces = MediaType.APPLICATION_JSON_VALUE)

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.cnadmin.webapi.controller.auth;
import lombok.RequiredArgsConstructor;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import top.charles7c.cnadmin.auth.config.properties.CaptchaProperties;
import top.charles7c.cnadmin.auth.model.request.LoginRequest;
import top.charles7c.cnadmin.auth.model.vo.LoginVO;
import top.charles7c.cnadmin.auth.service.LoginService;
import top.charles7c.cnadmin.common.config.properties.RsaProperties;
import top.charles7c.cnadmin.common.model.vo.R;
import top.charles7c.cnadmin.common.util.CheckUtils;
import top.charles7c.cnadmin.common.util.ExceptionUtils;
import top.charles7c.cnadmin.common.util.RedisUtils;
import top.charles7c.cnadmin.common.util.SecureUtils;
/**
* 登录 API
*
* @author Charles7c
* @since 2022/12/21 20:37
*/
@Tag(name = "登录 API")
@RestController
@RequiredArgsConstructor
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public class LoginController {
private final LoginService loginService;
private final CaptchaProperties captchaProperties;
@SaIgnore
@Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证")
@PostMapping("/login")
public R<LoginVO> login(@Validated @RequestBody LoginRequest loginRequest) {
// 校验验证码
String captchaKey = RedisUtils.formatKey(captchaProperties.getKeyPrefix(), loginRequest.getUuid());
String captcha = RedisUtils.getCacheObject(captchaKey);
CheckUtils.exIfBlank(captcha, "验证码已失效");
RedisUtils.deleteCacheObject(captchaKey);
CheckUtils.exIfCondition(() -> !captcha.equalsIgnoreCase(loginRequest.getCaptcha()), "验证码错误");
// 用户登录
String rawPassword = ExceptionUtils
.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword(), RsaProperties.PRIVATE_KEY));
CheckUtils.exIfBlank(rawPassword, "密码解密失败");
String token = loginService.login(loginRequest.getUsername(), rawPassword);
return R.ok(new LoginVO().setToken(token));
}
@SaIgnore
@Operation(summary = "用户退出", description = "注销用户的当前登录")
@Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxxxxxxx",
in = ParameterIn.HEADER)
@PostMapping("/logout")
public R logout() {
CheckUtils.exIfCondition(() -> !StpUtil.isLogin(), "Token 无效");
StpUtil.logout();
return R.ok();
}
}