Spring Spring Security+JWTログイン-3の実装(登録コスト、ログインapiの作成)
48552 ワード
必要なすべてのセキュリティ構成が完了しました.いよいよログインと登録APIの作成時間です.
ただし、APIを定義する前に、APIが使用するリクエストおよびレスポンスペイロード(DTO)を定義する必要があります.
まず、これらのペイロードを定義します.
要求が無効または予期せぬ場合、APIに例外が発生します.
異なるタイプの例外に対して、異なるHTTPステータスコードを使用して応答したい場合があります.
1. AppException
最後に、完全なコードは、アイデンティティコントローラへのログインおよびサブスクリプションのためのAPIを含む.
APIは、自己開発サーバ上で実行される反応クライアント上でアクセスされます.CORSを許可するには、パッケージ
このような構造が現れる.
その
プロジェクトを実行します.
postmanで実行すると、
こうして出てきた
ログインAPIを使用してアクセストークンを取得すると、以下に示すように、アクセストークンを要求ヘッダに渡すことによって保護されたAPIを呼び出すことができる.
これでSpring SecurityとJWTを使用して、強力な認証ロジックと認証ロジックを構築しました.
ありがとうございます
複数のSpring Security+JWTの例を参照してください.
昔の和弦がたくさんあったので...
とにかく私はこうしました
何か気になることがあったらメッセージをお願いします~
ただし、APIを定義する前に、APIが使用するリクエストおよびレスポンスペイロード(DTO)を定義する必要があります.
まず、これらのペイロードを定義します.
payload
またはdto
パッケージを作成してください.ここで作成します.ペイロード要求(DTO)クラス
1.ログイン要求
package com.example.polls.payload;
import javax.validation.constraints.NotBlank;
public class LoginRequest {
@NotBlank
private String usernameOrEmail;
@NotBlank
private String password;
public String getUsernameOrEmail() {
return usernameOrEmail;
}
public void setUsernameOrEmail(String usernameOrEmail) {
this.usernameOrEmail = usernameOrEmail;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.会員申請
import javax.validation.constraints.*;
@Getter @Setter
public class SignUpRequest {
@NotBlank
@Size(min = 4, max = 40)
private String name;
@NotBlank
@Size(min = 3, max = 15)
private String username;
@NotBlank
@Size(max = 40)
@Email
private String email;
@NotBlank
@Size(min = 6, max = 20)
private String password;
}
応答応答ペイロード(DTO)
1.JWT認証応答
@Getter @Setter
public class JwtAuthenticationResponse {
private String accessToken;
private String tokenType = "Bearer";
public JwtAuthenticationResponse(String accessToken) {
this.accessToken = accessToken;
}
}
2. APIResponse
@Getter @Setter
public class ApiResponse {
private Boolean success;
private String message;
public ApiResponse(Boolean success, String message) {
this.success = success;
this.message = message;
}
}
例外の作成
要求が無効または予期せぬ場合、APIに例外が発生します.
異なるタイプの例外に対して、異なるHTTPステータスコードを使用して応答したい場合があります.
exception
という名前のパッケージを作成して例外を作成1. AppException
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class AppException extends RuntimeException {
public AppException(String message) {
super(message);
}
public AppException(String message, Throwable cause) {
super(message, cause);
}
}
2. BadRequestException
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
public BadRequestException(String message, Throwable cause) {
super(message, cause);
}
}
3. ResourceNotFoundExceptionimport org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
private String resourceName;
private String fieldName;
private Object fieldValue;
public ResourceNotFoundException( String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
public String getResourceName() {
return resourceName;
}
public String getFieldName() {
return fieldName;
}
public Object getFieldValue() {
return fieldValue;
}
}
ログインコントローラ
最後に、完全なコードは、アイデンティティコントローラへのログインおよびサブスクリプションのためのAPIを含む.
controller
というパッケージを生成して中に書きましょう~
import com.example.polls.exception.AppException;
import com.example.polls.model.Role;
import com.example.polls.model.RoleName;
import com.example.polls.model.User;
import com.example.polls.payload.ApiResponse;
import com.example.polls.payload.JwtAuthenticationResponse;
import com.example.polls.payload.LoginRequest;
import com.example.polls.payload.SignUpRequest;
import com.example.polls.repository.RoleRepository;
import com.example.polls.repository.UserRepository;
import com.example.polls.security.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.validation.Valid;
import java.net.URI;
import java.util.Collections;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserRepository userRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
JwtTokenProvider tokenProvider;
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if(userRepository.existsByUsername(signUpRequest.getUsername())) {
return new ResponseEntity(new ApiResponse(false, "Username is already taken!"),
HttpStatus.BAD_REQUEST);
}
if(userRepository.existsByEmail(signUpRequest.getEmail())) {
return new ResponseEntity(new ApiResponse(false, "Email Address already in use!"),
HttpStatus.BAD_REQUEST);
}
// Creating user's account
User user = new User(signUpRequest.getName(), signUpRequest.getUsername(),
signUpRequest.getEmail(), signUpRequest.getPassword());
user.setPassword(passwordEncoder.encode(user.getPassword()));
Role userRole = roleRepository.findByName(RoleName.ROLE_USER)
.orElseThrow(() -> new AppException("User Role not set."));
user.setRoles(Collections.singleton(userRole));
User result = userRepository.save(user);
URI location = ServletUriComponentsBuilder
.fromCurrentContextPath().path("/api/users/{username}")
.buildAndExpand(result.getUsername()).toUri();
return ResponseEntity.created(location).body(new ApiResponse(true, "User registered successfully"));
}
}
CORSの有効化
APIは、自己開発サーバ上で実行される反応クライアント上でアクセスされます.CORSを許可するには、パッケージ
config
を作成し、WebMvcConfig
クラスを作成します.import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final long MAX_AGE_SECS = 3600;
@Value("${app.cors.allowedOrigins}")
private String[] allowedOrigins;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(allowedOrigins)
.allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.maxAge(MAX_AGE_SECS);
}
}
許可されているCORS構成ソースはアプリケーションです.propertiesファイルからインポートします.プロパティ・ファイルに次の内容を追加します.# Comma separated list of allowed origins
app:
cors:
allowedOrigins: http://localhost:3000
草このような構造が現れる.
その
DateAudit
の書類をBaseEntity
と書きました.プロジェクトを実行します.
postmanで実行すると、
会員収入
ログイン
こうして出てきた
保護されたAPIの呼び出し
ログインAPIを使用してアクセストークンを取得すると、以下に示すように、アクセストークンを要求ヘッダに渡すことによって保護されたAPIを呼び出すことができる.
Authorization: Bearer <accessToken>
JwtAuthentiacationFilter
ヘッダからaccessTokenを読み取り、検証し、APIへのアクセスを許可/拒否する.これでSpring SecurityとJWTを使用して、強力な認証ロジックと認証ロジックを構築しました.
ありがとうございます
複数のSpring Security+JWTの例を参照してください.
昔の和弦がたくさんあったので...
とにかく私はこうしました
何か気になることがあったらメッセージをお願いします~
Reference
この問題について(Spring Spring Security+JWTログイン-3の実装(登録コスト、ログインapiの作成)), 我々は、より多くの情報をここで見つけました https://velog.io/@modsiw/Spring-Spring-Security-JWT-로그인-예제-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol