1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-09 04:51:56 +00:00

more features and fix database/mysql:jwt example

This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-11-24 14:58:02 +02:00
parent 4d857ac53f
commit 11e21150d0
24 changed files with 767 additions and 153 deletions

View File

@@ -0,0 +1,18 @@
# docker build -t myapp .
# docker run --rm -it -p 8080:8080 myapp:latest
FROM golang:latest AS builder
RUN apt-get update
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
WORKDIR /go/src/app
COPY go.mod .
RUN go mod download
# cache step
COPY . .
RUN go install
FROM scratch
COPY --from=builder /go/bin/myapp .
ENTRYPOINT ["./myapp"]

View File

@@ -0,0 +1,44 @@
# BasicAuth + MySQL & Docker Example
## ⚡ Get Started
Download the folder.
### Install (Docker)
Install [Docker](https://www.docker.com/) and execute the command below
```sh
$ docker-compose up --build
```
### Install (Manually)
Run `go build` or `go run main.go` and read below.
#### MySQL
Environment variables:
```sh
MYSQL_USER=user_myapp
MYSQL_PASSWORD=dbpassword
MYSQL_HOST=localhost
MYSQL_DATABASE=myapp
```
Download the schema from [migration/db.sql](migration/db.sql) and execute it against your MySQL server instance.
<http://localhost:8080>
```sh
username: admin
password: admin
```
```sh
username: iris
password: iris_password
```
The example does not contain code to add a user to the database, as this is out of the scope of this middleware. More features can be implemented by end-developers.

View File

@@ -0,0 +1,32 @@
version: '3.1'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: dbpassword
MYSQL_DATABASE: myapp
MYSQL_USER: user_myapp
MYSQL_PASSWORD: dbpassword
tty: true
volumes:
- ./migration:/docker-entrypoint-initdb.d
app:
build: .
ports:
- 8080:8080
environment:
PORT: 8080
MYSQL_USER: user_myapp
MYSQL_PASSWORD: dbpassword
MYSQL_DATABASE: myapp
MYSQL_HOST: db
restart: on-failure
healthcheck:
test: ["CMD", "curl", "-f", "tcp://db:3306"]
interval: 30s
timeout: 10s
retries: 10
depends_on:
- db

View File

@@ -0,0 +1,8 @@
module myapp
go 1.15
require (
github.com/go-sql-driver/mysql v1.5.0
github.com/kataras/iris/v12 master
)

View File

@@ -0,0 +1,113 @@
package main
import (
"context"
"database/sql"
"fmt"
"os"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/basicauth"
_ "github.com/go-sql-driver/mysql" // lint: mysql driver.
)
// User is just an example structure of a user,
// it MUST contain a Username and Password exported fields
// or/and complete the basicauth.User interface.
type User struct {
ID int64 `db:"id" json:"id"`
Username string `db:"username" json:"username"`
Password string `db:"password" json:"password"`
Email string `db:"email" json:"email"`
}
// GetUsername returns the Username field.
func (u User) GetUsername() string {
return u.Username
}
// GetPassword returns the Password field.
func (u User) GetPassword() string {
return u.Password
}
func main() {
dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?parseTime=true&charset=utf8mb4&collation=utf8mb4_unicode_ci",
getenv("MYSQL_USER", "user_myapp"),
getenv("MYSQL_PASSWORD", "dbpassword"),
getenv("MYSQL_HOST", "localhost"),
getenv("MYSQL_DATABASE", "myapp"),
)
db, err := connect(dsn)
if err != nil {
panic(err)
}
// Validate a user from database.
allowFunc := func(ctx iris.Context, username, password string) (interface{}, bool) {
user, err := db.getUserByUsernameAndPassword(context.Background(), username, password)
return user, err == nil
}
opts := basicauth.Options{
Realm: basicauth.DefaultRealm,
ErrorHandler: basicauth.DefaultErrorHandler,
Allow: allowFunc,
}
auth := basicauth.New(opts)
app := iris.New()
app.Use(auth)
app.Get("/", index)
app.Listen(":8080")
}
func index(ctx iris.Context) {
user := ctx.User()
ctx.JSON(user)
}
func getenv(key string, def string) string {
v := os.Getenv(key)
if v == "" {
return def
}
return v
}
type database struct {
*sql.DB
}
func connect(dsn string) (*database, error) {
conn, err := sql.Open("mysql", dsn)
if err != nil {
return nil, err
}
err = conn.Ping()
if err != nil {
conn.Close()
return nil, err
}
return &database{conn}, nil
}
func (db *database) getUserByUsernameAndPassword(ctx context.Context, username, password string) (User, error) {
query := fmt.Sprintf("SELECT * FROM %s WHERE %s = ? AND %s = ? LIMIT 1", "users", "username", "password")
rows, err := db.QueryContext(ctx, query, username, password)
if err != nil {
return User{}, err
}
defer rows.Close()
if !rows.Next() {
return User{}, sql.ErrNoRows
}
var user User
err = rows.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
return user, err
}

View File

@@ -0,0 +1,22 @@
CREATE DATABASE IF NOT EXISTS myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE myapp;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
password varchar(255) NOT NULL,
email varchar(255) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO users (username,password,email)
VALUES
('admin', 'admin', 'kataras2006@hotmail.com'),
("iris", 'iris_password', 'iris-go@outlook.com');
SET FOREIGN_KEY_CHECKS = 1;