아래 프로젝트를 참고하여 진행 (내용이 약간다름)

https://github.com/codingspecialist/Springboot-Security-JWT

 

codingspecialist/Springboot-Security-JWT

Contribute to codingspecialist/Springboot-Security-JWT development by creating an account on GitHub.

github.com

 

위 프로젝트 연구

https://ondolroom.tistory.com/690

 

spring boot // Springboot-Security-JWT 프로젝트 분석

연구할 프로젝트 https://github.com/codingspecialist/Springboot-Security-JWT codingspecialist/Springboot-Security-JWT Contribute to codingspecialist/Springboot-Security-JWT development by creating an..

ondolroom.tistory.com

 

사전 정보

https://ondolroom.tistory.com/687

 

spring boot // 토큰 기반 / JWT 정보

아래 사이트를 참고하여 정리합니다 https://velopert.com/2350 [JWT] 토큰(Token) 기반 인증에 대한 소개 | VELOPERT.LOG 소개 토큰(Token) 기반 인증은 모던 웹서비스에서 정말 많이 사용되고 있습니다. 여러분.

ondolroom.tistory.com

 

현재 프로젝트 (아래 코드 설명을 참고하려면 이곳을 확인)

https://github.com/jaybon1/springwork/tree/master/jwtEx01

 

jaybon1/springwork

Contribute to jaybon1/springwork development by creating an account on GitHub.

github.com

 

프로젝트 명 생성

 

 

필요한 의존성 추가

---------

 

프로젝트 구조

----------

 

 

pom.xml

JWT 의존성 추가

		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>3.4.1</version>
		</dependency>

--------

 

application.yml

----

 

RestApiController.java

@RequestMapping("api/v1") // 공통 진입경로 확인

@Autowired 를 사용하지 않고 DI할 것들에 final 붙이고 @RequiredArgsConstructor를 붙여주면 똑같은 효과

---------

 

 

SecurityConfig.java

메서드를 IOC 하기 위한 @Bean

 

1. STATELESS로 만들면 jsessoinId를 만들지 않는다

2. /login 경로로 접근시 해당필터에 걸리게 된다

3. 해당 경로로 접근시 ROLE이 맞는 사람만 접속 하도록 한다

.anyRequest().permitAll() 나머지 요청은 모두 허용한다

-----------

 

CorsConfig.java

cors()옵션 - 기타도메인의 자바스크립트 요청을 거부

@CrossOrigin은 컨트롤러 클래스가 아닌 메서드에 거는 것을 추천

전역적으로 설정하려면 아래와 같이 파일 생성하여 입력

 

 

User.java

원래 model에는 setter를 달면 안된다 - DTO를 이용하자

--

 

LoginRequestDto.java

로그인 데이터를 전송하기위한 DTO

 

 

PrincipalDetails.java

UserDetails를 상속하기 위한 클래스

User 객체를 컴포지션 한다

()-> 화살표 함수를 사용하면 GrantedAuthority와 관련된 클래스를 지정하지 않고도 자동으로 만들 수 있다

---------

 

 

PrincipalDetailsService.java

DB에서 유저를 검색하여 있으면 UserDetails를 리턴한다

-------

 

 

JwtAuthenticationFilter.java

------

 

1. attemptAuthentication은 인증 요청시에 실행 된다 (/login)

2. ObjectMapper는 데이터가 어떠한 형식으로 들어오더라도 값을 변환하여 객체에 담아준다

3. attemptAuthentication을 커스텀하면 UsernamePasswordAuthenticationToken을 직접 만들어 줘야한다

4. 아래 주석 참고

--------

 

1. Authentication 객체에서 PrincipalDetails를 가져온다

2. 클레임들을 삽입하고 암호알고리즘을 추가하여 JWT토큰을 만든다

3. 만들어진 토큰을 헤더에 넣는다

-------

 

 

JwtAuthorizationFilter.java

BasicAuthenticationFilter는 헤더전문 필터

--

 

팁 : 내가 new 한 클래스는 Autowired가 안된다

매개변수로 userRepository를 받아서 전역변수에 담아준다

----

 

1. 인증필터가 끝나면 인가필터로 넘어오는 것

2. 헤더값에 JWT토큰이 있는지 확인하여 없으면 돌려보낸다

3. 토큰이 있다면 JWT토큰에서 베리어와 패딩을 뺀 순수한 토큰값을 가져온다

---

 

토큰 검증하기
시크릿 키값과 함께 암호화된 파일을 풀어서 유저네임을 가져온다
암호화를 풀고 유저네임을 가져온 것 자체가 검증이 끝났다는 것

---

 

인가 1번방식

1. 위에서 검증이 끝난 유저네임으로 리파지토리에서 데이터를 받아
UserDetails 를 상속받은 PrincipalDetails를 만든다

2. UsernamePasswordAuthenticationToken을 만들고
authenticationManager를 사용하지 않고 usernamePasswordAuthenticationToken를 이용하여 Authentication 제작

3. 시큐리티 세션저장공간에 authentication을 넣는다.

----

 

인가 2번 방식

1. 위에서 검증이 끝난 유저네임으로 리파지토리에서 데이터를 받아 sessionUser라는 DTO에 넣어준다

2. 시큐리티세션(authentication)이 아닌 일반세션에 넣어준다

----

 

컨트롤러에서 일반세션 테스트용 메서드를 매핑한다

--

 

콘솔창 확인

--

 

포스트맨 확인

--

 

인가 3번 방식


클레임에 ROLE을 넣어서 바로어썬티케이션 만들기
(이렇게 만들면 리파지토리에서 유저를 가져올 필요도 없다 / 토큰에서 인증한 데이터로 만들면되기 때문)

--

 

인가 4번 방식

1번 방식을 개선한 방식

----

 

마지막으로 필터체인으로 다시 돌아간다

 

 

@inject : 모든 자바코드에서 적용가능

@autowired : 스프링 전용 어노테이션

autowired의 기본원리는 생성자를 만드는 것이다

IOC된 객체들을 찾아서 DI해주는 것

--------------

 

안드로이드를 예시로 JWT 진행순서

레트로핏 post 요청 

-> jwt필터에서 로그인프로세스 요청을 낚아챔

-> UserDetailsService타서 DB에서 확인 + 어썬티케이션 생성 되는것 확인 + 로그인

-> 세션을 만드는게 아니라 토큰을 만듬

-> 토큰에 권한을 부여 (인증+권한 - 슈도코드)

-> 토큰을 리스폰스 (헤더에 담아서 보냄) - 헤더 안에 authorization 필드 생성 

header: {
	authorization:
		"베리어 토큰"
}

base64로 인코딩, 디코딩 (헤더에 담고 인코딩 디코딩 하는 것은 전부 규칙이며 커스텀 가능)

 

-> 재요청시 토큰을 실어서 서버로 보냄

-> 서버에서 내가 만든 토큰인지 확인 (시크릿 키값으로 확인 = 서명검증)

 

토큰은 탈취 당할 수 있기 때문에 유효시간이 있다

토큰을 탈취 당하지 않기 위해서는 SSL HTTPS 를 써야함

-

 

소켓통신 : stateful (연결지속)
HTTP : stateless (상태 지속 안됨)
HTTP + 세션 : stateful 
HTTP + 웹소켓 : stateful 
JWT : stateless

-----------

 

@RequiredArgsConstructor가 붙어 있으면 final 이 붙어있는 클래스를 받는 생성자를 자동으로 만들어준다

 

이렇게 안에 매개변수를 넣을 수 있다

 

연구할 프로젝트

https://github.com/codingspecialist/Springboot-Security-JWT

 

codingspecialist/Springboot-Security-JWT

Contribute to codingspecialist/Springboot-Security-JWT development by creating an account on GitHub.

github.com

 

application.yml

ssl의 특징인 포트번호 443이 보임( 맞나? )

키 
키저장소비밀번호
키저장소타입
키별명

 

BootSecurityApplication.java

Connector를 만든 이유는 http와 https를 같이 쓰기 위함인 것 같다

postProcessContext도 마찬가지로 http와 https를 같이 쓰기 위함인 것 같다

 

Connecter 참고 링크

https://velog.io/@max9106/Spring-Boot-%EB%82%B4%EC%9E%A5-%EC%9B%B9-%EC%84%9C%EB%B2%84-z8k66l0suf

 

[Spring Boot] 내장 웹 서버 - 2 (스프링부트 HTTPS / HTTP2)

HTTPS HTTPS(SSL프로토콜 위에서 돌아가는 프로토콜)을 사용하려면 키스토어(인증서)를 만들어야한다. 티미널을 열어 프로젝트 위치에서 아래의 명령어를 입력한다. `keytool -genkey -alias spring -storetype

velog.io

 

postProcessContext 참고 링크

https://kimjongmo.github.io/spring/spring-boot-redirect-http-to-https

 

스프링부트 HTTP요청을 HTTPS 둘다 사용하기 « Kimjongmo's Blog

스프링부트 HTTPS 적용 스프링 부트 HTTPS 적용시키기 프로젝트에 자가 서명을 이용한 후 http요청을 하게 되면 아래와 같은 응답을 받게된다. 당연히도 해당 포트는 이제 더이상 http요청을 받지않��

kimjongmo.github.io

 

 

PublicRestApiController.java

컨트롤러 클래스 위에 @RequestMapping을 이용함(공통 경로)

다른 도메인에서도 접근가능 하도록 @CrossOrigin 사용

 

@RequestMapping 참고 링크

https://woolbro.tistory.com/43

 

Spring MVC 예제 - @RequestMapping 어노테이션 예제

이번 포스팅은 이전에 작성한 직원 관리 예제를 가지고 설명을 하려고 합니다. [Java/Spring-framework] - Spring MVC 예제 - 직원 관리 프로그램 Spring MVC 예제 - 직원 관리 프로그램 이번 포스팅은 Spring MVC.

woolbro.tistory.com

 

@CrossOrigin 참고 링크

http://jmlim.github.io/spring/2018/12/11/spring-boot-crossorigin/

 

스프링 부트에서 크로스도메인 이슈 처리하기. (@CrossOrigin 어노테이션을 사용) · 기억하기 위한 �

스프링 부트에서 크로스도메인 이슈 처리하기. (@CrossOrigin 어노테이션을 사용) 11 Dec 2018 | Spring CORS Cross Domain 크로스도메인 이슈란? Ajax 등을 통해 다른 도메인의 서버에 url(data)를 호출할 경우 XMLH

jmlim.github.io

 

 

DbInit.java

DB를 초기화 하는 것 같은 이름이다

CommandLineRunner는 스프링 구동시 사용할 코드들을 적는 기능을 포함한다

유추해보면 유저데이터를 모두삭제하고 역할별로 3개를 넣은듯 하다

 

 

UserPrincipal.java

getAuthorities에 permissions와 roles를 둘다 담았다 

 

 

SecurityConfiguration.java

아래링크에 따르면

@Bean 외부 라이브러리 등 개발자가  직접 제어불가능한 것들을 Bean으로 만들 때 사용

@Component 는 개발자가 직접 만든 클래스를 Bean으로 등록하기 위함

 

DB 관련 내용으로

데이터베이스 인증용 Provider 라고함

 

1. csrf 기능을 무효화하고 세션을 Stateless 상태로바꿈
2. authentication 인증,  authorization 권한을 무엇으로 설정할지 세팅
3. URI 입장권한

 

@Bean 참고 링크

https://galid1.tistory.com/494

 

Spring - @Bean 어노테이션과 @Component 어노테이션(DI) - 2

@Component, @Bean 프로그램이 거대해 짐에 따라 XML 을 이용하여 IOC Container 를 설정하는 것이 점점 어려워졌고 때문에 Annotation(@) 이란 것이 등장했다(이하 어노테이션). 어노테이션은 코드에 메타데��

galid1.tistory.com

 

DaoAuthenticationProvider 참고 링크

https://javaiyagi.tistory.com/431

 

스프링 시큐리티를 이용한 보안 - 1부 인증

현재 맡고 있는 프로젝트의 Rest Api 가 보안이 전혀 돼 있지 않아서, 보안을 강화하는 작업을 시작했다. 보안이 전혀 돼 있지 않기 때문에, 사용자 아이디/비밀번호 정보가 없어도, Rest Api 를 호출�

javaiyagi.tistory.com

 

 

JwtProperties.java

SECRET은 비밀코드인듯

 

 

JwtAuthenticationFilter.java

JwtAuthenticationFilter :  Form Login시 걸리는 Filter이다. UsernamePasswordAuthenticationFilter를 상속한 JwtAuthenticationFilter을 등록하였다. 이 필터는 HttpServletRequest에서 사용자가 Form으로 입력한 로그인 정보를 인터셉트해서 AuthenticationManager에게 Authentication 객체를 넘겨준다.

UsernamePasswordAuthenticationFilter : HttpServletRequest에서 사용자가 보낸 아이디와 패스워드를 인터셉트

AuthenticationManager(ProviderManager) : 아이디 패스워드를 UsernamePasswordAuthenticationToken(인증용 객체)로만들어서 전달하면 UserDetailsService가 UserDetails를 만들어 줄것이다

 

attemptAuthentication : Authentication을 리턴 (securitycontextholder, securitycontext 에 담는 것?)

 

successfulAuthentication : 헤더에 JWT 헤더스트링과 토큰을 추가하는 듯함

 

 

참고 링크

https://javaiyagi.tistory.com/431

 

스프링 시큐리티를 이용한 보안 - 1부 인증

현재 맡고 있는 프로젝트의 Rest Api 가 보안이 전혀 돼 있지 않아서, 보안을 강화하는 작업을 시작했다. 보안이 전혀 돼 있지 않기 때문에, 사용자 아이디/비밀번호 정보가 없어도, Rest Api 를 호출�

javaiyagi.tistory.com

 

참고 링크

https://coding-start.tistory.com/153

 

Spring boot - Spring Security(스프링 시큐리티) 란? 완전 해결!

오늘 포스팅할 내용은 Spring Security이다. 사실 필자는 머리가 나빠서 그런지 모르겠지만, 아무리 구글링을 통해 스프링 시큐리티를 검색해도 이렇다할 명쾌한 해답을 얻지 못했다. 대부분 이론적

coding-start.tistory.com

 

 

JwtAuthorizationFilter.java

JwtAuthorizationFilter : Form Login에서 인증된 이후의 요청에 대해 Header 인증을 담당할 Filter이다.

BasicAuthenticationFilter 는 헤더만 분석하는 필터이다

BasicAuthenticationFilter를 상속한 JwtAuthorizationFilter를 등록하였다.  JWT 기반 인증에서 실제 JWT 토큰의 인증이 이루어질 필터 부분이다.

Authentication은 스프링 내부에서만 사용하는 Authentication이다. 

 

JwtToken안에 있는 payload 즉, Claims를 꺼내고 권한정보까지 만들어 인증처리된 Authentication을 생성한다.

생성한 Authentication을 SecurityContextHolder에 저장한다.

스프링의 나머지 FilterChain들을 수행할 수 있도록 doFilter(request,response)를 호출한다.

 

getUsernamePasswordAuthentication : JWT에서 Authentication을 추출하는 듯함

 

참고 링크

https://mia-dahae.tistory.com/122

 

[Authorization]JWT 토큰 사용하여 사용자정보 parsing하기

JWT토큰을 사용하여 사용자를 식별하기 위해 Header에 해당 정보를 넣을 것이다. Header에 다음과 같은 형식으로 전달하고 주고 받을 예정이다. { Authorization: Bearer token } 또한 모든 요청에 대해서 acces

mia-dahae.tistory.com

 

 

LoginViewModel

로그인 전용 모델인가?

 

 

--------------

세션 방식??

1. AuthenticationFilterAnotherParam Bean 등록
2. UsernamePasswordAuthenticationFilter 등록 
3. attemptAuthentication 메서드에서 넘어온 데이터를 session에 저장
4. 인증 성공 시 successfulAuthentication에서 setAuthenticationSuccessHandler를 등록
5. Controller에서(SuccessHandler에서 지정한 url) session에 저장한 데이터 사용
6. 인증 실패 시 unsuccessfulAuthentication에서 3번에서 저장했던 데이터를 Session에서 제거

참고 링크

https://okky.kr/article/358004

 

OKKY | spring security에서 로그인 parameter를 추가해서 받을 수 잇나요??

username하고 password가 기본값인데 필요한 추가해서 데이터를 받아서 비교할 순 없나요?? 혹시  가능한지 알고싶고, 가능하면 무엇을 custom해야하는지 알려주시면 감사드립니다.ㅠㅠ

okky.kr

 

 

아래 사이트를 참고하여 정리합니다

https://velopert.com/2350

 

[JWT] 토큰(Token) 기반 인증에 대한 소개 | VELOPERT.LOG

소개 토큰(Token) 기반 인증은 모던 웹서비스에서 정말 많이 사용되고 있습니다. 여러분이 API 를 사용하는 웹서비스를 개발한다면, 토큰을 사용하여 유저들의 인증작업을 처리하는것이 가장 좋은

velopert.com

 

토큰기반 인증

API를 사용하는 웹서비스를 개발한다면, 토큰을 사용하여 유저들의 인증작업을 처리하는 것이 좋은방법

 

토큰기반 인증 시스템을 선택하는 이유

1. Stateless 서버

Stateful 서버
- 클라이언트에게 요청을 받을 때마다 클라이언트의 상태를 계속유지
- 해당 정보를 서비스 제공에 이용
- ex) 세션을 유지하는 웹서버 - 서버컴퓨터의 메모리 또는 데이터베이스

Stateless 서버
- 상태를 유지 하지 않는다
- 클라이언트측에서 들어오는 요청만으로 작업을 처리
- 클라이언트와 서버의 연결고리가 없기 때문에 서버의 확장성이 높아진다

 

2. 모바일 어플리케이션에 적합
- 안드로이드/ios에서는 쿠키는 이상적이지 않다 (쿠키 컨테이너를 사용해야하는 등)
- 토큰기반은 이 번거로움을 해결할 수 있다

 

3.보안
- 해킹의 위험을 무조건 벗어나는 것은 아니지만 보안을 높일 수 있다

 

토큰기반 인증 시스템을 사용하는 서비스

트위터/ 페이스북/ 깃헙 등

 

토큰을 사용하게 되는 이유

1. 서버기반 인증의 문제점

세션 - 로그인 중인 유저수가 늘어나면 서버의 램이나 데이터베이스의 성능에 무리를 줄 수 있다

확장성 - 트래픽을 감당하기 위해 여러개의 프로세서를 돌리거나, 여러대의 서버 컴퓨터를 추가해야한다. 과정이 복잡해진다.

CORS - 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계 되어있다. 따라서 쿠키를 여러도메인에서 관리하는 것은 번거롭다

 

토큰 기반 시스템의 작동 원리

Stateless 시스템에서 유저의 인증정보를 서버나 세션에 담아 두지 않는다

토큰기반 시스템의 구현방식

1. 유저가 아이디와 비밀번호로 로그인
2. 서버측에서 해당 계정정보를 검증
3. 계정정보가 정확하면 서버->유저 signed 토큰을 발급
4. 클라이언트 측에서 전달 받은 토큰을 저장
5. 요청시마다 토큰을 함께 서버에 전달 (http 요청의 헤더에 토큰값을 포함 시켜 전달)

 

토큰의 장점

무상태(Stateless) + 확장성(Scalability)

서버 확장에 적합(분산 서버라면 어떠한 서버로 요청이 들어가던 상관이 없다)

1. 보안
- 쿠키를 사용함으로 인해 발생하는 취약점이 사라짐(토큰 취약점은 존재)

2. Extensibility 확장성
- Scalability와는 다른 개념
- 로그인 정보가 사용되는 분야를 확장하는 것
- 토큰을 사용하여 다른 서비스에서도 권한을 공유 할 수 있다
(구글 네이버 등의 계정으로 내 사이트에 로그인을 할 수 있는 것처럼)
- 토큰에 선택적인 권한만 부여하여 발급 할 수 있다 (프로필 정보 가져오는 권한 O / 페북에 글쓰는 권한 X)

3. 여러 플랫폼 및 도메인
- 한가지 서비스가 아닌 여러 서비스 및 도메인에서 요청이 정상적으로 처리 된다
- 어플리케이션 응답 부분에 Access-Control-Allow-Origin: * 를 포함시켜서 처리
- 이미지, css, js, html 파일 등은 CDN에서 제공, 서버측에서는 API만 다루도록 설계 가능

아래는 CDN 정보

https://cdn.hosting.kr/cdn%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94/

 

https://cdn.hosting.kr/cdn%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94/

 

cdn.hosting.kr

 

4. 웹 표준 기반

토큰 기반 인증 시스템의 구현체인 JWT는 웹표준에 등록되어있어서 여러 환경에서 지원이 되고 수많은 회사의 인프라스트럭쳐에서 사용 되고 있음

 

-----------------

 

JWT

 

기본정보

두 개체에서 JSON 객체를 사용하여 가볍고 자가수용적인 방식으로 정보를 안전성 있게 전달

1. 수많은 프로그래밍 언어에서 지원됨

2. 자가수용적
- 필요한 모든정보를 자체적으로 지니고 있음
- 토큰의 기본정보 / 전달할 정보 / 토큰 검증 signature

3. 쉽게 전달 가능
- HTTP의 헤더나 URL의 파라미터로 전달 할 수 있음

 

JWT의 사용처

1. 회원인증
- 유저가 로그인 되어 있는지 신경 쓸 필요없이 유저가 요청할 때 토큰만 확인하면 됨
- 세션관리가 필요 없어서 서버 자원을 아낄 수 있음

2. 정보교류
- 두 개체 사이에 안정성 있게 정보를 교환하기에 좋은 방법
- 정보가 sign 되어 있기 때문에 정보를 보낸 이가 바뀌거나 정보가 조작되었는지 검증 가능

 

JWT의 생김새

JWT는 . 으로 구분하여 3가지 문자열로 되어 있음

aaaa.bbbb.cccc

(aaaa는 헤더, bbbb는 내용, cccc는 서명)

JWT 토큰을 만들때는 JWT를 담당하는 라이브러리가 자동으로 인코딩 및 해싱 작업을 해줌

 

헤더

헤더는 두가지 정보를 지니고 있다

typ : 토큰의 타입을 지정한다 (즉 JWT임을 알림)

alg : 해싱 알고리즘을 지정, 보통 HMAC SHA256 또는 RSA가 사용됨, 서명 부분에서 토큰을 검증할 때 사용

{
  "typ": "JWT",
  "alg": "HS256"
}

위 헤더내용을 공백과 엔터를 없애고 base64로 인코딩

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

 

 

정보

payload 라고 하며 토큰에 담을 정보가 들어있음.
정보들 각각을 claim이라고 부름 (name / value 의 한쌍으로 이루어져 있음)

클레임의 종류
1. 등록된(registered) 클레임
- 등록된 클레임의 사용은 선택적이다
- 서비스에서 필요한 정보가 아닌, 토큰에 대한 정보들을 담기 위하여 이름이 정해진 클레임
- iss : 토큰 발급자
- sub : 토큰 제목
- aud : 토큰 대상자
- exp : 토큰의 만료시간 (무조건 현재시간의 이후로 설정해야함)
- nbf : Not Before, 토큰의 활성 날짜와 비슷한 개념, 이 날짜가 되기전엔 토큰이 처리되지 않음
- iat : 토큰이 발급된 시간, 토큰의 age를 판단
- jti : JWT의 고유식별자, 중복적인 처리를 방지하기 위해 사용, 일회용 토큰에 유용

2. 공개(public) 클레임
- 충돌이 방지된 이름을 가지고 있어야함
- 충돌을 방지하기 위해서는 클레임 이름을 URI 형식으로 지어야함

3. 비공개(private) 클레임
- 서버와 클라이언트의 협의하에 사용되는 클레임
- 공개 클레임과는 달리 이름이 중복되어 충돌 될 수 있으니 사용할 때 유의해야함

{
    "iss": "velopert.com",
    "exp": "1485270000000",
    "https://velopert.com/jwt_claims/is_admin": true,
    "userId": "11028373727102",
    "username": "velopert"
}

위 헤더내용을 공백과 엔터를 없애고 base64로 인코딩

eyJpc3MiOiJ2ZWxvcGVydC5jb20iLCJleHAiOiIxNDg1MjcwMDAwMDAwIiwiaHR0cHM6Ly92ZWxvcGVydC5jb20vand0X2NsYWltcy9pc19hZG1pbiI6dHJ1ZSwidXNlcklkIjoiMTEwMjgzNzM3MjcxMDIiLCJ1c2VybmFtZSI6InZlbG9wZXJ0In0

 

 

payload 
- 등록된클레임 - 요청자, 만료시간은 꼭넣자
- 공개된클레임 - URI를 사용
- 비공개클레임 - 비밀번호 이메일 등을 제외한 유저네임, 프라이머리키, 권한 등

토큰에는 패스워드등 중요정보는 넣으면 안된다

 

 

 

라고 한다

 

서명

헤더의 인코딩 값 + 정보의 인코딩 값 + 비밀키로 해쉬

서명부분은 해싱하기 때문에 디코딩이 안됨

 

JWT가 잘 완성 되었는지 검증

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

 

 

https://github.com/codingspecialist/InstagramClone-Android-Firestore

 

여러액티비티에서 툴바 + 드로어블 사용하려면

헬퍼를 이용해야한다

 

메인

    private void setupBottomNavigationView(){
        BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
        BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationView);
        Menu menu = bottomNavigationView.getMenu();
        MenuItem menuItem = menu.getItem(ACTIVITY_NUM);
        menuItem.setChecked(true);
    }

 

layout_bottom_navigation_view.xml

  
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:background="@drawable/white_grey_border_top"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:labelVisibilityMode="unlabeled"
            app:menu="@menu/bottom_navigation_menu">

        </com.google.android.material.bottomnavigation.BottomNavigationView>

    </RelativeLayout>
</merge>

 

 

+ Recent posts