полностью работают регистрация, логин, аутентификация

This commit is contained in:
Sergey Chubaryan 2024-07-20 23:13:30 +03:00
parent 4cf54225b1
commit 59dc02c3b1
7 changed files with 58 additions and 22 deletions

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}"
}
]
}

8
db_init.sql Normal file
View File

@ -0,0 +1,8 @@
create table users (
id int generated always as identity,
login text unique not null,
secret text not null,
name text not null,
primary key (id)
);

13
dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM golang:1.22
WORKDIR /usr/src/app
COPY go.mod go.sum ./
RUN go mod download && go mod verify
EXPOSE 8080
COPY . .
RUN go build -v -o /usr/local/bin/app ./...
CMD ["app"]

13
main.go
View File

@ -4,7 +4,6 @@ import (
"backend/src" "backend/src"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jackc/pgx" "github.com/jackc/pgx"
@ -16,10 +15,10 @@ func main() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
keyBytes, err := x509.MarshalPKCS8PrivateKey(key) // keyBytes, err := x509.MarshalPKCS8PrivateKey(key)
if err != nil { // if err != nil {
panic(err) // panic(err)
} // }
connConf, err := pgx.ParseConnectionString("postgres://postgres:postgres@localhost:5432/postgres") connConf, err := pgx.ParseConnectionString("postgres://postgres:postgres@localhost:5432/postgres")
if err != nil { if err != nil {
@ -31,7 +30,7 @@ func main() {
panic(err) panic(err)
} }
jwtUtil := src.NewJwtUtil(string(keyBytes)) jwtUtil := src.NewJwtUtil(key)
bcryptUtil := src.NewBcrypt() bcryptUtil := src.NewBcrypt()
db := src.NewDB(sqlDb) db := src.NewDB(sqlDb)
userService := src.NewUserService(src.UserServiceDeps{ userService := src.NewUserService(src.UserServiceDeps{
@ -46,7 +45,7 @@ func main() {
userGroup := r.Group("/user") userGroup := r.Group("/user")
userGroup.POST("/create", src.NewUserCreateHandler(userService)) userGroup.POST("/create", src.NewUserCreateHandler(userService))
userGroup.POST("/login", src.NewUserCreateHandler(userService)) userGroup.POST("/login", src.NewUserLoginHandler(userService))
dummyGroup := r.Group("/dummy") dummyGroup := r.Group("/dummy")
dummyGroup.Use(src.NewAuthMiddleware(userService)) dummyGroup.Use(src.NewAuthMiddleware(userService))

View File

@ -21,7 +21,7 @@ type dbImpl struct {
} }
func (d *dbImpl) CreateUser(ctx context.Context, dto UserDTO) (*UserDTO, error) { func (d *dbImpl) CreateUser(ctx context.Context, dto UserDTO) (*UserDTO, error) {
query := `insert into users (login, secret, name) values (?, ?, ?) returning id;` query := `insert into users (login, secret, name) values ($1, $2, $3) returning id;`
row := d.db.QueryRowContext(ctx, query, dto.Login, dto.Secret, dto.Name) row := d.db.QueryRowContext(ctx, query, dto.Login, dto.Secret, dto.Name)
id := "" id := ""
@ -38,11 +38,11 @@ func (d *dbImpl) CreateUser(ctx context.Context, dto UserDTO) (*UserDTO, error)
} }
func (d *dbImpl) GetUserById(ctx context.Context, id string) (*UserDTO, error) { func (d *dbImpl) GetUserById(ctx context.Context, id string) (*UserDTO, error) {
query := `select (id, login, secret, name) from users where id = ?;` query := `select id, login, secret, name from users where id = $1;`
row := d.db.QueryRowContext(ctx, query, id) row := d.db.QueryRowContext(ctx, query, id)
dto := &UserDTO{} dto := &UserDTO{}
err := row.Scan(dto) err := row.Scan(&dto.Id, &dto.Login, &dto.Secret, &dto.Name)
if err == nil { if err == nil {
return dto, nil return dto, nil
} }
@ -54,11 +54,11 @@ func (d *dbImpl) GetUserById(ctx context.Context, id string) (*UserDTO, error) {
} }
func (d *dbImpl) GetUserByLogin(ctx context.Context, login string) (*UserDTO, error) { func (d *dbImpl) GetUserByLogin(ctx context.Context, login string) (*UserDTO, error) {
query := `select (id, login, secret, name) from users where login = ?;` query := `select id, login, secret, name from users where login = $1;`
row := d.db.QueryRowContext(ctx, query, login) row := d.db.QueryRowContext(ctx, query, login)
dto := &UserDTO{} dto := &UserDTO{}
err := row.Scan(dto) err := row.Scan(&dto.Id, &dto.Login, &dto.Secret, &dto.Name)
if err == nil { if err == nil {
return dto, nil return dto, nil
} }

View File

@ -1,6 +1,7 @@
package src package src
import ( import (
"crypto/rsa"
"fmt" "fmt"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
@ -16,19 +17,19 @@ type JwtUtil interface {
Parse(tokenStr string) (JwtPayload, error) Parse(tokenStr string) (JwtPayload, error)
} }
func NewJwtUtil(privateKey string) JwtUtil { func NewJwtUtil(privateKey *rsa.PrivateKey) JwtUtil {
return &jwtUtil{ return &jwtUtil{
privateKey: privateKey, privateKey: privateKey,
} }
} }
type jwtUtil struct { type jwtUtil struct {
privateKey string privateKey *rsa.PrivateKey
} }
func (j *jwtUtil) Create(user UserDTO) (string, error) { func (j *jwtUtil) Create(user UserDTO) (string, error) {
payload := JwtPayload{UserId: user.Id} payload := &JwtPayload{UserId: user.Id}
token := jwt.NewWithClaims(&jwt.SigningMethodHMAC{}, payload) token := jwt.NewWithClaims(jwt.SigningMethodRS256, payload)
tokenStr, err := token.SignedString(j.privateKey) tokenStr, err := token.SignedString(j.privateKey)
if err != nil { if err != nil {
return "", err return "", err
@ -37,15 +38,15 @@ func (j *jwtUtil) Create(user UserDTO) (string, error) {
} }
func (j *jwtUtil) Parse(tokenStr string) (JwtPayload, error) { func (j *jwtUtil) Parse(tokenStr string) (JwtPayload, error) {
token, err := jwt.ParseWithClaims(tokenStr, JwtPayload{}, func(t *jwt.Token) (interface{}, error) { token, err := jwt.ParseWithClaims(tokenStr, &JwtPayload{}, func(t *jwt.Token) (interface{}, error) {
return j.privateKey, nil return &j.privateKey.PublicKey, nil
}) })
if err != nil { if err != nil {
return JwtPayload{}, err return JwtPayload{}, err
} }
if payload, ok := token.Claims.(JwtPayload); ok { if payload, ok := token.Claims.(*JwtPayload); ok {
return payload, nil return *payload, nil
} }
return JwtPayload{}, fmt.Errorf("cant get payload") return JwtPayload{}, fmt.Errorf("cant get payload")

View File

@ -32,11 +32,11 @@ func NewUserCreateHandler(userService UserService) gin.HandlerFunc {
Name: params.Name, Name: params.Name,
}) })
if err == ErrUserExists { if err == ErrUserExists {
ctx.AbortWithError(400, err) ctx.Data(400, "plain/text", []byte(err.Error()))
return return
} }
if err != nil { if err != nil {
ctx.AbortWithError(500, err) ctx.Data(500, "plain/text", []byte(err.Error()))
return return
} }