728x90

[관리자페이지] Admin Page - Admin - SiginIn 페이지 #7 Token 체크 리다이렉트


관리자 페이지 화면 구현은 Nextjs를 사용합니다.

Nextjs를 사용하기 위해서는 node.js를 설치해야합니다.

https://nodejs.org/en/download

설치 후에는 npx create-next-app@latest 를 이용해서 nextjs 프로젝트를 생성해 줍니다.

npx create-next-app@latest

app router를 사용합니다.
프로 젝트 생성 후에는 app 디렉토리에 admin과 signin 디렉토리를 각각 생성해 줍니다.

.
┗src
   ┗app
     ┗ admin
         ┗ page.tsx
     ┗ signin
         ┗ page.tsx

각 디렉토리에 page.tsx를 생성해 주고 간단한 텍스트 작성 후에

npm run dev

로 실행시킵니다.

// src/app/admin/page.tsx

export default function Admin(){
    return <>admin</>
}

// src/app/Signin/page.tsx
export default async function Signin() {
    return <>Sign In</>
}

 

 

Nextjs middleware를 사용해서 admin page로 접속 시 1) 토큰이 없거나, 2) 토큰이 있지만 만료 되었을 경우 SignIn 페이지로 이동하는 로직을 작성해 줍니다.

토큰은 cookie에 있고

먼저 토큰을 체크하는 로직을 작성해 줍니다.

 

 

https://nextjs.org/docs/app/building-your-application/routing/middleware

 

Routing: Middleware | Next.js

Learn how to use Middleware to run code before a request is completed.

nextjs.org

//src/middleware.ts
import {NextRequest, NextResponse} from 'next/server'

export function middleware(request: NextRequest) {

    if (request.nextUrl.pathname.startsWith('/admin')) {
        const cookie =request.cookies.get("token");
        if(!cookie){
            return NextResponse.redirect(new URL('/signin', request.url))
        }
    }


}

export const config = {
    matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)',],
}

 

728x90
728x90

pip install 로 mariadb 를 설치시 발생할수 있는 에러

This error typically indicates that MariaDB Connector/C, a dependency which      must be preinstalled, is not found.

 

 

sudo apt install libmariadb3 libmariadb-dev

 

 

https://askubuntu.com/questions/1438002/mariadb-connector-c-is-not-installed

728x90
728x90

[관리자 페이지] Admin Page - 회원가입 구현하기 #6 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://jwt.io/)

아이디 / 패스워드로 사용자 로그인을 성공하면 jwt 를 발급합니다.

accessToken, refreshToken 2개를 발급합니다.

import jwt
from datetime import datetime, timedelta
from dotenv import load_dotenv
import os

load_dotenv(os.path.join(os.path.dirname(__file__), "..", "..", ".env"))


class CommonUtils:
    ACCESS_TOKEN_EXPIRE = os.getenv("ACCESS_TOKEN_EXPIRE")
    REFRESH_TOKEN_EXPIRE = os.getenv("REFRESH_TOKEN_EXPIRE")
    SECRET_KEY = os.getenv("SECRET_KEY")
    @staticmethod
    def create_token(user_info):
        today = datetime.now()

        access_token_expire_time = today + timedelta(seconds=float(CommonUtils.ACCESS_TOKEN_EXPIRE))
        refresh_token_expire_time = today + timedelta(seconds=float(CommonUtils.REFRESH_TOKEN_EXPIRE))

        access_token_payload = {"iat": today, "iss": "hiio420.com", "exp": access_token_expire_time,
                                "sub": "Access Token",
                                "userId": user_info.id}
        access_token = jwt.encode(access_token_payload, "secret", algorithm="HS256")
        refresh_token_payload = {"iat": today, "iss": "hiio420.com", "exp": refresh_token_expire_time,
                                 "sub": "Refresh Token",
                                 "userId": user_info.id}
        refresh_token = jwt.encode(refresh_token_payload, CommonUtils.SECRET_KEY, algorithm="HS256")
        return {"access_token": access_token, "refresh_token": refresh_token}

.env 파일을 사용합니다.

.env 파일에는 token의 만료 시간과 토큰 발행에 사용할 시크릿 문자열이 있습니다.

유틸을 만든 이유는 나중에 이부분만 다른 프로젝트에도 사용될 수 있지 않을까하는 생각에 만들었습니다.


## UserService class
...
 
    def get_token(self, user_info: UserModel) -> TokenModel:
        token = CommonUtils.create_token(user_info)
        return TokenModel(accessToken=token["access_token"], refreshToken=token["refresh_token"])

UserService에 get_token을 만들고 user_info를 파라미터로 전달합니다.
get_token은 TokenModel을 반환합니다.

from pydantic import BaseModel, Field


class TokenModel(BaseModel):
    accessToken: str = Field("", title="Access Token")
    refreshToken: str = Field("", title="Refresh Token")

@api_main.post("/signin",response_model=TokenModel)
def signin(user: UserWithPasswordModel):
    user: UserModel = userService.sign_in(user)
    return userService.get_token(user)

728x90

+ Recent posts