LoginController.java 4.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * 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;

19 20
import java.util.List;

21 22 23 24 25 26 27 28 29 30 31 32
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
33
import cn.hutool.core.bean.BeanUtil;
34 35 36

import top.charles7c.cnadmin.auth.model.request.LoginRequest;
import top.charles7c.cnadmin.auth.model.vo.LoginVO;
37
import top.charles7c.cnadmin.auth.model.vo.RouteVO;
38
import top.charles7c.cnadmin.auth.model.vo.UserInfoVO;
39
import top.charles7c.cnadmin.auth.service.LoginService;
40
import top.charles7c.cnadmin.common.constant.CacheConsts;
41
import top.charles7c.cnadmin.common.model.dto.LoginUser;
42 43 44 45
import top.charles7c.cnadmin.common.model.vo.R;
import top.charles7c.cnadmin.common.util.ExceptionUtils;
import top.charles7c.cnadmin.common.util.RedisUtils;
import top.charles7c.cnadmin.common.util.SecureUtils;
46
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
47
import top.charles7c.cnadmin.common.util.validate.ValidationUtils;
48 49
import top.charles7c.cnadmin.system.model.vo.UserDetailVO;
import top.charles7c.cnadmin.system.service.UserService;
50 51 52 53 54 55 56 57 58 59

/**
 * 登录 API
 *
 * @author Charles7c
 * @since 2022/12/21 20:37
 */
@Tag(name = "登录 API")
@RestController
@RequiredArgsConstructor
60
@RequestMapping("/auth")
61 62 63
public class LoginController {

    private final LoginService loginService;
64
    private final UserService userService;
65 66 67 68 69 70

    @SaIgnore
    @Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证")
    @PostMapping("/login")
    public R<LoginVO> login(@Validated @RequestBody LoginRequest loginRequest) {
        // 校验验证码
71
        String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, loginRequest.getUuid());
72
        String captcha = RedisUtils.getCacheObject(captchaKey);
73
        ValidationUtils.throwIfBlank(captcha, "验证码已失效");
74
        RedisUtils.deleteCacheObject(captchaKey);
75
        ValidationUtils.throwIfNotEqualIgnoreCase(loginRequest.getCaptcha(), captcha, "验证码错误");
76 77

        // 用户登录
78 79
        String rawPassword =
            ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword()));
80
        ValidationUtils.throwIfBlank(rawPassword, "密码解密失败");
81
        String token = loginService.login(loginRequest.getUsername(), rawPassword);
82
        return R.ok(LoginVO.builder().token(token).build());
83 84 85 86
    }

    @SaIgnore
    @Operation(summary = "用户退出", description = "注销用户的当前登录")
87
    @Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxx-xxxx-xxxx-xxxx",
88 89 90 91 92 93
        in = ParameterIn.HEADER)
    @PostMapping("/logout")
    public R logout() {
        StpUtil.logout();
        return R.ok();
    }
94 95 96 97 98

    @Operation(summary = "获取用户信息", description = "获取登录用户信息")
    @GetMapping("/user/info")
    public R<UserInfoVO> getUserInfo() {
        LoginUser loginUser = LoginHelper.getLoginUser();
99 100 101 102
        UserDetailVO userDetailVO = userService.get(loginUser.getId());
        UserInfoVO userInfoVO = BeanUtil.copyProperties(userDetailVO, UserInfoVO.class);
        userInfoVO.setPermissions(loginUser.getPermissions());
        userInfoVO.setRoles(loginUser.getRoles());
103
        return R.ok(userInfoVO);
104
    }
105 106 107 108 109 110 111 112

    @Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
    @GetMapping("/route")
    public R<List<RouteVO>> listMenu() {
        Long userId = LoginHelper.getUserId();
        List<RouteVO> routeTree = loginService.buildRouteTree(userId);
        return R.ok(routeTree);
    }
113
}