@ -0,0 +1,56 @@
|
||||
package com.studyingspace.controller;
|
||||
|
||||
import com.studyingspace.common.Result;
|
||||
import com.studyingspace.dto.LoginRequest;
|
||||
import com.studyingspace.dto.LoginResponse;
|
||||
import com.studyingspace.dto.RegisterRequest;
|
||||
import com.studyingspace.entity.User;
|
||||
import com.studyingspace.repository.UserRepository;
|
||||
import com.studyingspace.utils.JwtUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/auth")
|
||||
@Tag(name = "用户认证", description = "登录注册接口")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JwtUtils jwtUtils;
|
||||
|
||||
@PostMapping("/register")
|
||||
@Operation(summary = "用户注册", description = "注册新用户")
|
||||
public Result<String> register(@RequestBody RegisterRequest request) {
|
||||
if (userRepository.existsByUsername(request.getUsername())) {
|
||||
return Result.error("用户名已存在");
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
userRepository.save(user);
|
||||
|
||||
return Result.success("注册成功");
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "用户登录", description = "登录并返回 JWT token")
|
||||
public Result<LoginResponse> login(@RequestBody LoginRequest request) {
|
||||
User user = userRepository.findByUsername(request.getUsername()).orElse(null);
|
||||
if (user == null) {
|
||||
return Result.error(401, "用户名不存在");
|
||||
}
|
||||
|
||||
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
|
||||
return Result.error(401, "密码错误");
|
||||
}
|
||||
|
||||
String token = jwtUtils.generateToken(user.getUsername());
|
||||
return Result.success(new LoginResponse(token, user.getUsername()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.studyingspace.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.studyingspace.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginResponse {
|
||||
private String token;
|
||||
private String username;
|
||||
|
||||
public LoginResponse(String token, String username) {
|
||||
this.token = token;
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.studyingspace.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RegisterRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package com.studyingspace.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(unique = true, nullable = false)
|
||||
private String username;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String password;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
createTime = LocalDateTime.now();
|
||||
updateTime = LocalDateTime.now();
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void onUpdate() {
|
||||
updateTime = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.studyingspace.repository;
|
||||
|
||||
import com.studyingspace.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
Optional<User> findByUsername(String username);
|
||||
boolean existsByUsername(String username);
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package com.studyingspace.utils;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.Date;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Component
|
||||
public class JwtUtils {
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
|
||||
@Value("${jwt.expiration}")
|
||||
private Long expiration;
|
||||
|
||||
private Key getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public String generateToken(String username) {
|
||||
Date now = new Date();
|
||||
Date expiryDate = new Date(now.getTime() + expiration);
|
||||
|
||||
return Jwts.builder()
|
||||
.setSubject(username)
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiryDate)
|
||||
.signWith(getSigningKey(), SignatureAlgorithm.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = Jwts.parserBuilder()
|
||||
.setSigningKey(getSigningKey())
|
||||
.build()
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
|
||||
return claims.getSubject();
|
||||
}
|
||||
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
Jwts.parserBuilder()
|
||||
.setSigningKey(getSigningKey())
|
||||
.build()
|
||||
.parseClaimsJws(token);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/auth/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function register(data) {
|
||||
return request({
|
||||
url: '/auth/register',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
Loading…
Reference in new issue