Tekies Communityバックエンドの作成-6
今.今まで制作していたRDBを送ってきます.
毎回コインをつけて化粧直しをするので
だから申請します.構文をpropertiesに挿入する場合は、次の操作を行います.
db.を自動的に作成します.createが終わったらdrop...updateがあればそれを使いますが、なければ作ってください.
これで、Securityとjwtでログインを実現します.
では今はGradlebuildでは、次の依存設定を行う必要があります.
ただし、AccessTokenにRefreshTokenの機能を追加すると、よりクリーンになる可能性があります.筆者は.初めまして...まずはAccessTokenをしましょうしました.
前に作ったものもあります.dbを変更するには...以降、JPAモードを使用する場合は、EntityにRDBを適用する方式で行う.
つまりその前にもdbを全部削除していました.上のddl-auto update...
だからEntityからユーザーが変わりました.
これを変えたら、サービスも変えなければなりません.
では、サービスとエンティティの準備が完了しました.
そしてsecurityを設定したら….大きく振って移動すると...起動できません...
だからSecurityConfigJavaを次のように記述します.
そしてここで終わるのではなく、フィルターでマウントします.
さっき安全措置で言った部分がいいです.
情報がこんなによく出ている.
ここでテストできますが、postmanに移動してテストを行うと...
登録してログインすると、
うん.何も変わってないの?
リクエストで受け取ったタイトルを見たら
そのまま受け取りました.では.
これを持って検索するために、私は大きな値を保存しました.
問い合わせたら...
出てこない...
フィルタリングプロセスに関連する部分が問題のようです.だからこの部分を理解するために.
自らfilterの役を演じることにした.Controllerの情報セクションを変更しました
それからまた調べて...
よく撮れました...
このようにトークンとセキュリティ設定を使用しています...バックエンド・アイテムを次に行う場合は、refreshとaccessを使用して他のフィルタを適用する必要があります.
残りの記事ではjenkinsによるec 2自動構築&導入を行います.
毎回コインをつけて化粧直しをするので
だから申請します.構文をpropertiesに挿入する場合は、次の操作を行います.
db.を自動的に作成します.createが終わったらdrop...updateがあればそれを使いますが、なければ作ってください.
spring.jpa.hibernate.ddl-auto=update
これで、Securityとjwtでログインを実現します.
では今はGradlebuildでは、次の依存設定を行う必要があります.
implementation ('org.springframework.boot:spring-boot-starter-security')
implementation ('org.springframework.boot:spring-boot-starter-validation')
implementation group : 'com.googlecode.json-simple', name: 'json-simple', version: '1.1'
implementation ('io.jsonwebtoken:jjwt:0.9.1')
AccessTokenによってアクセスされる方式でトークン方式で行われます.ただし、AccessTokenにRefreshTokenの機能を追加すると、よりクリーンになる可能性があります.筆者は.初めまして...まずはAccessTokenをしましょうしました.
前に作ったものもあります.dbを変更するには...以降、JPAモードを使用する場合は、EntityにRDBを適用する方式で行う.
つまりその前にもdbを全部削除していました.上のddl-auto update...
だからEntityからユーザーが変わりました.
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int tc_num;
private String tc_id;
private String tc_password;
private String tc_email;
@ElementCollection(fetch = FetchType.EAGER)
private List<String> roles = new ArrayList<>();
@Builder
public User(String tc_id, String tc_password, String tc_email) {
this.tc_id = tc_id;
this.tc_password = tc_password;
this.tc_email = tc_email;
this.roles = Collections.singletonList("ROLE_USER");
}
public void update(String tc_password, String tc_email) {
this.tc_password = tc_password;
this.tc_email = tc_email;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return tc_password;
}
@Override
public String getUsername() {
return tc_id;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Spring Securityのuserdetailを継承するとArreget部分が...これは発表せざるを得ない部分です.キャラクターもstreamは、ロールをstringとして作成し、次の手順で変換する必要があります.これを変えたら、サービスも変えなければなりません.
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public User loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findtc_passwordBytc_id(username);
}
}
userServiceの高セキュリティの詳細サービスを継承し、次の変更を行います.では、サービスとエンティティの準備が完了しました.
そしてsecurityを設定したら….大きく振って移動すると...起動できません...
だからSecurityConfigJavaを次のように記述します.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and()
.csrf().disable()
.formLogin().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
こうなると、まず大振りに対して一時的な方法をとるが、追加で変更しなければならない.この部分はjwt部分が終わってからまた来ましょう.@Component
@RequiredArgsConstructor
public class JwtAuthenticationProvider {
private String secretKey = "secret";
private long tokenValidTime = 1000L * 60 * 60;
@Autowired
private UserService userService;
// JWT 토큰 생성
public String createToken(String userPk, List<String> roles) {
Claims claims = Jwts.claims().setSubject(userPk); // JWT payload 에 저장되는 정보단위
claims.put("roles", roles); // 정보는 key / value 쌍으로 저장된다.
Date now = new Date();
return Jwts.builder()
.setClaims(claims) // 정보 저장
.setIssuedAt(now) // 토큰 발행 시간 정보
.setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time
.signWith(SignatureAlgorithm.HS256, secretKey) // 사용할 암호화 알고리즘과
// signature 에 들어갈 secret값 세팅
.compact();
}
// JWT 토큰에서 인증 정보 조회
public Authentication getAuthentication(String token) {
User user = userService.loadUserByUsername(this.getUserPk(token));
return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities());
}
// 토큰에서 회원 정보 추출
public String getUserPk(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
}
// Request의 Header에서 token 값을 가져옵니다. "X-AUTH-TOKEN" : "TOKEN값'
public String resolveToken(HttpServletRequest request) {
String token = null;
Cookie cookie = WebUtils.getCookie(request, "X-AUTH-TOKEN");
if(cookie != null) token = cookie.getValue();
return token;
}
// 토큰의 유효성 + 만료일자 확인
public boolean validateToken(String jwtToken) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken);
return !claims.getBody().getExpiration().before(new Date());
} catch (Exception e) {
return false;
}
}
}
トークンの暗号解読プロセスや有効期限の確認などの機能を書いてから適用します.そしてここで終わるのではなく、フィルターでマウントします.
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtAuthenticationProvider jwtAuthenticationProvider;
public JwtAuthenticationFilter(JwtAuthenticationProvider provider) {
jwtAuthenticationProvider = provider;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = jwtAuthenticationProvider.resolveToken(request);
if(token != null && jwtAuthenticationProvider.validateToken(token)){
Authentication authentication = jwtAuthenticationProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
}
もしそうなら.また来ます.Security設定セクションで次の変更を行います.@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private JwtAuthenticationProvider jwtAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.cors().and()
.csrf().disable()
.formLogin().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtAuthenticationProvider), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
そうすれば、コントローラに行って登録部分を処理すればいいのです. @PostMapping("/v1/user/login")
@JsonProperty("requestDto")
@ApiOperation(value = "로그인")
public UserLoginResponseDto login(@RequestBody UserLoginRequestDto requestDto,HttpServletResponse response ){
User user= userService.findPasswordById(requestDto);
if(user==null){
throw new IllegalArgumentException("잘못된 계정정보입니다.");
}
System.out.println("여기까지됨123" + user.getUsername() + user.getRoles());
String token = jwtAuthenticationProvider.createToken(user.getUsername(), user.getRoles());
response.setHeader("X-AUTH-TOKEN", token);
Cookie cookie = new Cookie("X-AUTH-TOKEN", token);
cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setSecure(true);
response.addCookie(cookie);
return new UserLoginResponseDto(user);
}
また、ログアウト部分を設定することもできます. @PostMapping("/v1/user/logout")
@ApiOperation(value = "로그아웃")
public void logout(HttpServletResponse response){
Cookie cookie = new Cookie("X-AUTH-TOKEN", null);
cookie.setHttpOnly(true);
cookie.setSecure(false);
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
}
タグを使用してページ情報クエリーコントローラを作成します @GetMapping("/v1/user/info")
@ApiOperation(value = "마이페이지토큰이용")
public UserResponseDto getInfo(){
Object details = SecurityContextHolder.getContext().getAuthentication();
if(details == null) {
System.out.println("비어있음");
}
else {
System.out.println("안비어있어욤");
System.out.println(details);
}
if(details != null && !(details instanceof String)) return new UserLoginResponseDto((User) details);
}
このようにして作成してSwagerに移動して確認しておきますさっき安全措置で言った部分がいいです.
情報がこんなによく出ている.
ここでテストできますが、postmanに移動してテストを行うと...
登録してログインすると、
うん.何も変わってないの?
リクエストで受け取ったタイトルを見たら
そのまま受け取りました.では.
これを持って検索するために、私は大きな値を保存しました.
問い合わせたら...
出てこない...
フィルタリングプロセスに関連する部分が問題のようです.だからこの部分を理解するために.
自らfilterの役を演じることにした.Controllerの情報セクションを変更しました
@GetMapping("/v1/user/info")
@ApiOperation(value = "마이페이지토큰이용")
public UserResponseDto getInfo(HttpServletRequest request){
System.out.println("Zzz");
System.out.println(request.getHeader("X-AUTH-TOKEN") + "^.^"); // 토큰값봐보기
String token = request.getHeader("X-AUTH-TOKEN"); //토큰 헤더에서 직접가져오기
System.out.println(token+ "^.^");
String userpk = jwtAuthenticationProvider.getUserPk(token); //토큰으로 아이디값조회
System.out.println(userpk + " sss");
// Object details = SecurityContextHolder.getContext().getAuthentication();
/* if(details == null) {
System.out.println("비어있음");
}
else {
System.out.println("안비어있어욤");
System.out.println(details);
}
if(details != null && !(details instanceof String)) return new UserLoginResponseDto((User) details);
*/
System.out.println("반환값없음");
return userService.findById(userpk); //아이디값으로 조회한 결과반환
}
こうして...呜呜...フィルターを使ったらもったいないそれからまた調べて...
よく撮れました...
このようにトークンとセキュリティ設定を使用しています...バックエンド・アイテムを次に行う場合は、refreshとaccessを使用して他のフィルタを適用する必要があります.
残りの記事ではjenkinsによるec 2自動構築&導入を行います.
Reference
この問題について(Tekies Communityバックエンドの作成-6), 我々は、より多くの情報をここで見つけました https://velog.io/@tekies09/Tekies-Community-백엔드-만들기-6テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol