Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 시스템디자인
- 글또
- 코드트리
- SemVer
- 글또 10기
- TS
- Semantic Versioning
- ASP.NET
- 캐나다취준
- framer-motion
- Framer motion
- 알고리즘
- JSBridge
- react
- framer
- 개발자 원칙
- CSS방법론
- 이펙티브타입스크립트
- CSS
- useState
- 캐나다개발자
- React-Router-Dom
- Effective Typescript
- JUNCTION2023
- VS Code
- 타입스크립트
- 회고
- 테오의 스프린트
- 개발자를 위한 글쓰기 가이드
- typescript
Archives
- Today
- Total
큰 꿈은 파편이 크다!!⚡️
Microsoft.IdentityModel 인증 + 리액트 본문
Microsoft.IdentityModel
C#계의 oidc에서 제일 유명한 오픈소스 라이브러리로는 IdentityServer4(ids4)가 있다. 하지만 이번에 하는 작업이 이 라이브러리를 붙일 정도는 아니라고 생각해서 닷넷에서 제공하는 기본 인증(마이크로소프트가 제공하면 기본 이라고 생각하는 나)을 사용해보고 싶었다. 하지만 이 기본 인증 라이브러리도 설치가 필요했다..🫠
- 스펙: dotnet5
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
Flow
클라이언트(웹, 리액트) ↔ 서버(api 서버이자 인증 서버, ASP.NET) 간의 인증 흐름은 이렇게 구성했다.
ProtectedRoute
를 가진 어떤 페이지에 접속한다- 세션 스토리지에 토큰, 유저정보가 있는지 확인한다
- 있으면 children page를 반환한다
- 없으면,
- 로그인 페이지를 반환한다
- 로그인한다 ⇒ 서버로 로그인 요청하는 api를 날린다
- 서버가 비밀번호를 확인하고
- no ⇒ return null (고도화하게 되면 실패 이유까지 반환)
- yes ⇒ return access token
- 받은 결과에 따라 children page 또는 에러 이유를 표시한다
How to
Startup.cs
- 인증을 사용할 것이고, jwt방식을 사용할 것이라는 선언을 한다.
🧨 Troubleshoot: 처음에 issuer을 그냥 키값이 될만한 아무 문자열 값으로 넣었더니 오류가 났다.. 검색해보니 꼭 issuer ip/domain을 넣어야하는것같기도?
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key_here")),
ValidIssuer = "http://127.0.0.1:5000",
ValidAudience = "your_audience_here"
};
}).AddCookie();
api controller class
- 클래스에 아래와 같은 Attribute를 추가하면, 인증을 통과한 사용자만 api를 호출할 수 있으며 그 외의 경우에는 401 Unauthorized 오류를 만날 수 있다.
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
사용자가 로그인할 AuthController.cs
- 하지만 로그인을 할 때에는 인증되지 않은 사용자가 api요청을 하는 것이기 때문에
[AllowAnonymous]
Attribute를 추가해서 이 api는 인증 안받아도 된다는 예외처리를 해준다. - 토큰을 발급할 때의 핵심은 issuer, audience, key 등을
Startup.cs
에서 작성했던대로 맞추는 것이다.
[AllowAnonymous]
[HttpPost("Login")]
public async Task<string> Login([FromBody] LoginModel model)
{
if (LoginSuccess(model)){
var user = Guid.NewGuid().ToString();
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
identity.AddClaim(new Claim(ClaimTypes.Name, user));
var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("your_secret_key_here")); // Replace with your secret key
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "http://127.0.0.1:5000", // Replace with your issuer
audience: "your_audience_here", // Replace with your audience
claims: identity.Claims,
expires: DateTime.Now.AddMinutes(30), // Token expiration time (adjust as needed)
signingCredentials: creds
);
// Serialize the token to a string
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
return accessToken;
}
return null;
}
LoginPage.tsx
- 토큰을 반환하면 리액트에서는 어딘가(ex. 세션 스토리지)에 저장한다.
if (result.data){
setAccessToken(result.data);
}
그리고 그 리액트에서 서버로 api 요청할때 auth header에 bearer로 추가한다
🧨 Troubleshoot: 원래는 axios 인스턴스를 만들어서 인스턴스의 속성에 추가하려고 했는데 레퍼런스가 잘못된 건지 먹히지 않아서 axios default에 직접 추가하게 되었다.
const GetAsync = async (path: string, parameters?: object) => {
axios.defaults.headers.common["Authorization"] = "Bearer " + getAccessToken();
return await axios.get(path, {
params: parameters,
});
};
이제 리프레시 토큰을 해보려다가..(헉헉) 지금 만드는 프로젝트 특성상 이것까지는 필요하지 않을 것 같아서 더이상 진행하지 않았다.
단, 어떻게 할지는 두 가지 방법 정도를 생각했었다.
- getAccessToken 할때마다 jwt decode 해서 exp시간이 촉박하거나 초과했으면 access token 요청하는 api를 보낸다.
- api 호출할때마다 토큰 확인해서 필요하면 refresh 토큰을 같이 반환한다.
도움:
반응형
'기타 CS' 카테고리의 다른 글
[시스템 디자인 학습] Load balancer (1) | 2024.11.10 |
---|---|
ASP.NET으로 서버&리액트 프로젝트 서빙하기 (0) | 2024.02.04 |
“런타임”이라는 단어를 이제는 사용할거야 (0) | 2023.07.02 |
내가 정착한 VSCode 환경 설정 💞 소개 (0) | 2023.05.20 |
시맨틱 버전 관리 (Semantic Versioning) (0) | 2021.09.27 |