Golang: 인증 JWT 생성 #1
폴더 구조 소개
이 자습서에서는 일반적으로 사용하는 폴더 구조를 사용합니다.
├───앱
├───도메인
├───개체
│ └───도우미
├───인터페이스
│ └───http
└───서비스
└───사용자
├───저장소
│ └───포스트그레스
└───유스케이스
app
: go 프로그램이 처음 실행될 때 실행될 main.package를 포함합니다.domain
: 구조체 도메인을 포함합니다.entities/helper
: 도우미 기능이 포함되어 있습니다.interface/http
: 진고닉 라우팅 핸들러를 포함합니다.service
: 서비스 포함usecase
: 사용자 대신 유스케이스를 넣을 위치.repository
: 저장소를 넣을 위치이제 생성된 폴더에서
go mod init shellrean.com/auth
를 실행합니다.postgresql에서 테이블 생성
DBMS의 경우 이번에는 PostgreSQL을 사용하여 다음 사양의 사용자 이름으로 테이블을 생성합니다.
그런 다음 1명의 더미 사용자를 만들고 Bcrypt-Generator의 온라인 도구를 사용하여 bcrypt에서 자유롭게 암호를 생성하도록 합니다.
## 도메인 파일 생성
user.go
파일을 만들고 domain
폴더에 저장하면 이 파일에 도메인 구조와 사용자 인터페이스를 만듭니다.package domain
import (
"time"
"context"
)
type User struct {
ID int64 `json:"id"`
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=6"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type UserUsecase interface {
Authentication(ctx context.Context, ur DTOUserLoginRequest) (DTOTokenResponse, error)
RefreshToken(ctx context.Context, ur DTOTokenResponse) (DTOTokenResponse, error)
}
type UserRepository interface {
GetByID(ctx context.Context, id int64) (User, error)
GetByEmail(ctx context.Context, email string) (User, error)
}
domain.go 파일을 생성한 다음 동일한 폴더에 저장합니다. 이 파일의 토큰에 대해 도메인을 생성합니다.
package domain
type TokenDetails struct {
AccessToken string
RefreshToken string
AtExpires int64
RtExpires int64
}
파일 저장소 만들기
main_user.go
파일을 생성하고 services/user/repository/postgres
폴더에 저장하면 데이터베이스에서 데이터를 검색하는 저장소 기능을 생성합니다.package postgres
import (
"context"
"database/sql"
"shellrean.com/auth/domain"
)
type postgresUserRepository struct {
Conn *sql.DB
}
func NewPostgresUserRepository(Conn *sql.DB) domain.UserRepository {
return &postgresUserRepository{
Conn,
}
}
func (m *postgresUserRepository) GetByEmail(ctx context.Context, email string) (u domain.User, err error) {
query := `SELECT id,name,email,password,created_at,updated_at
FROM users WHERE email=$1`
err = m.Conn.QueryRowContext(ctx, query,email).
Scan(&u.ID,&t.Name,&t.Email,&t.Password,&t.CreatedAt,&t.UpdatedAt)
if err != nil {
return err
}
return
}
도우미 파일 만들기
token.go
파일을 생성하고 entities /helper
폴더에 저장하면 JWT로 작업을 수행하는 도우미 함수를 생성합니다.package helper
import (
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"shellrean.com/auth/domain"
)
func GenerateTokenDetail(td *domain.TokenDetails) {
td.AtExpires = time.Now().Add(time.Minute * 15).Unix()
td.RtExpires = time.Now().Add(time.Hour * 24 * 7).Unix()
}
func CreateAccessToken(key string, user domain.User, td *domain.TokenDetails) (err error) {
atClaims := jwt.MapClaims{}
atClaims["authorized"] = true
atClaims["user_id"] = user.ID
atClaims["exp"] = td.AtExpires
at := jwt.NewWithClaims(jwt.SigningMethodHS256, atClaims)
td.AccessToken, err = at.SignedString([]byte(key))
if err != nil {
return domain.ErrSessDecode
}
return
}
func ExtractToken(bearer string) (res string) {
str := strings.Split(bearer, " ")
if len(str) == 2 {
res = str[1]
return
}
return
}
func VerifyToken(key string, tokenString string) (*jwt.Token, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, domain.ErrSessDecode
}
return []byte(key), nil
})
if err != nil {
return nil, domain.ErrSessVerifation
}
return token, nil
}
func TokenValid(token *jwt.Token) error {
if _, ok := token.Claims.(jwt.Claims); !ok || !token.Valid {
return domain.ErrSessInvalid
}
return nil
}
func ExtractTokenMetadata(token *jwt.Token) map[string]interface{}{
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
return claims
}
return nil
}
이 시점에서 2개의 도메인 파일, 1개의 저장소 파일 및 1개의 도우미 파일을 만들었습니다. 다음 기사에서 계속하겠습니다.
Reference
이 문제에 관하여(Golang: 인증 JWT 생성 #1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shellrean/golang-auth-create-authentication-gin-jwt-1-41e4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)