package main
import (
_ "github.com/go-sql-driver/mysql"
"github.com/labstack/echo/middleware"
"github.com/labstack/echo"
"github.com/go-xorm/xorm"
"github.com/dgrijalva/jwt-go"
"time"
"net/mail"
"net/smtp"
"strings"
"fmt"
"os/exec"
"encoding/base64"
)
var Logger = middleware.LoggerWithConfig(middleware.LoggerConfig{
// 请求记录
Format: "LOG : ${time_rfc3339} ${status} - ${method} ${uri}\n",
})
var Recover = middleware.RecoverWithConfig(middleware.RecoverConfig{
// 程序恢复
})
var Secure = middleware.SecureWithConfig(middleware.SecureConfig{
// 安全保护
})
var CSRF = middleware.CSRFWithConfig(middleware.CSRFConfig{
// 防止攻击
})
var CORS = middleware.CORSWithConfig(middleware.CORSConfig{
// 请求跨域
})
var JwtServe = middleware.JWTWithConfig(middleware.JWTConfig{
// 访问认证
SigningKey: []byte("xxx"),
})
// 路由处理器
func RouteHandler(e *echo.Echo) {
a := e.Group("/api")
// User
a.GET("/login", LoginText)
}
func Run(PORT string) {
e := echo.New()
e.Use(
Logger,
)
e.Static("/", "./assets")
e.Static("dist", "./assets/dist")
/**/ RouteHandler(e)
e.File("/", "./assets/index.html")
e.Logger.Fatal(e.Start(PORT))
}
func main() { Run("localhost:4000") }
/*
项目依赖
github.com/go-sql-driver/mysql
github.com/go-xorm/xorm
github.com/dgrijalva/jwt-go
github.com/labstack/echo
*/
var xdb *xorm.Engine
func init() {
var err error
if xdb, err = xorm.NewEngine("mysql", "root:123456@/mydb?charset=utf8"); err != nil {
panic(err)
}
//xdb, _ = xorm.NewEngine("postgres", "host=127.0.0.1 user=root dbname=mydb sslmode=disable password=mypassword")
// 数据表同步
err = xdb.Sync2()
if err != nil {
panic(err)
}
}
// 测试接口
func LoginText(ctx echo.Context) error {
token := SendJWT("xxx", map[string]string{"Name": "小仙女"})
return ctx.JSON(200, token)
}
// 工具 ===============================================================================================================
// JWT分发器
func SendJWT(sign string, data interface{}) string {
// 创建一个新的令牌对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user": data,
"iat": time.Now().Unix(), // 发布时间
"nbf": time.Now().Unix(), // 有效起始时间
"exp": time.Now().Add(time.Hour * 24).Unix(), // 过期时间(一天)
"iss": nil, // 发行者
"sub": nil, // 标题
"aud": nil, // 客户(多发行者时使用)
"jti": nil, // 唯一标识
})
// 设置令牌签名
tokenString, err := token.SignedString([]byte(sign))
if err != nil {
panic(err)
}
return tokenString
}
// 邮件分发器
var EmailServe = New(Config{
Host: "smtp.sina.com",
Username: "upcyan@sina.com",
Password: "",
Port: 25,
})
// EmailServe.Send("", "", "")
type (
// 发件人邮箱配置
Config struct {
Host string // 邮箱服务器主机
Port int // 监听端口
Username string // 发件人的帐号
Password string // 发件人的密码
FromAddr string // 邮件头的'from'部分,它覆盖用户名
FromAlias string // 如果是空的,这是@用户名字段之前的第一部分
UseCommand bool // 如果要使用mail命令发送电子邮件而不是smtp,则使用命令启用它
// 主机,端口和密码将被忽略 仅适用于UNIX
}
Service interface {
Send(string, string, ...string) error
}
mailer struct {
config Config
fromAddr mail.Address
auth smtp.Auth
authenticated bool
}
)
// 创建并返回新的邮件服务
func New(cfg Config) Service {
m := &mailer{config: cfg}
addr := cfg.FromAddr
if addr == "" {
addr = cfg.Username
}
if cfg.FromAlias == "" {
if !cfg.UseCommand && cfg.Username != "" && strings.Contains(cfg.Username, "@") {
m.fromAddr = mail.Address{Name: cfg.Username[0:strings.IndexByte(cfg.Username, '@')], Address: addr}
}
} else {
m.fromAddr = mail.Address{Name: cfg.FromAlias, Address: addr}
}
return m
}
func (m *mailer) Send(subject string, body string, to ...string) error {
if m.config.UseCommand {
return m.sendCmd(subject, body, to)
}
return m.sendSMTP(subject, body, to)
}
func (m *mailer) sendSMTP(subject string, body string, to []string) error {
if !m.authenticated {
cfg := m.config
if cfg.Username == "" || cfg.Password == "" || cfg.Host == "" || cfg.Port <= 0 {
return fmt.Errorf("Username, Password, Host & Port cannot be empty when using SMTP!")
}
m.auth = smtp.PlainAuth("", cfg.Username, cfg.Password, cfg.Host)
m.authenticated = true
}
fullhost := fmt.Sprintf("%s:%d", m.config.Host, m.config.Port)
header := make(map[string]string)
header["From"] = m.fromAddr.String()
header["To"] = strings.Join(to, ",")
header["Subject"] = subject
header["Content-Type"] = "text/html; charset=\"utf-8\""
header["Content-Transfer-Encoding"] = "base64"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
return smtp.SendMail(
fmt.Sprintf(fullhost),
m.auth,
m.config.Username,
to,
[]byte(message),
)
}
func (m *mailer) sendCmd(subject string, body string, to []string) error {
header := make(map[string]string)
header["To"] = strings.Join(to, ",")
header["Subject"] = subject
header["Content-Type"] = "text/html; charset=\"utf-8\""
header["Content-Transfer-Encoding"] = "base64"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
cmd := exec.Command("sendmail", "-F", m.fromAddr.Name, "-f", m.fromAddr.Address, "-t")
_, err := cmd.CombinedOutput()
return err
}
转载于:https://my.oschina.net/upcyan/blog/1094085