xorm-echo-server

package app

import (
	_"github.com/go-sql-driver/mysql"
	"github.com/go-xorm/xorm"
	"github.com/labstack/echo/middleware"
	"github.com/labstack/echo"
	"github.com/dgrijalva/jwt-go"
	"encoding/base64"
	"math/rand"
	"net/mail"
	"net/smtp"
	"os/exec"
	"strings"
	"time"
	"log"
	"fmt"
)

func main() { app.Run("localhost:3000") }

/*
    项目依赖
    github.com/go-sql-driver/mysql
    github.com/go-xorm/xorm
    github.com/dgrijalva/jwt-go
    github.com/labstack/echo
*/

/*
	静态服务器 路由处理器 路由组 (子域)
	======================================== 中间件
	请求记录 Logger
	程序恢复 Recover
	安全保护 Secure
	防止攻击 CSRF
	请求跨域 CORS
	访问认证 JWT
	======================================== HTTP 请求 Request
	ctx.Bind()       // 读取 FORM && JSON
	ctx.Param()      // 读取动态路由/:id
	ctx.FormValue()  // 读取单个表单值
	ctx.FormFile()   // 读取文件
	ctx.FormParams() //
	======================================== HTTP 响应 Response
	ctx.String()     // 发送 字符串
	ctx.HTML()       // 发送 HTML
	ctx.JSON()       // 发送 JSON
	ctx.JSONP()      // 发送
	ctx.JSONPretty() // 发送 JSON带缩进
	ctx.JSONBlob()   // 发送
	ctx.JSONPBlob()  // 发送
	ctx.XML()        // 发送 XML
	ctx.XMLPretty()  // 发送 XML带缩进
	ctx.XMLBlob()    // 发送
	ctx.File()       // 发送 文件
	ctx.Attachment() // 发送 文件附件
	ctx.Inline()     // 发送 内联
	ctx.Blob()       // 发送
	ctx.Stream()     // 发送 数据流
	ctx.NoContent()  // 发送 带有状态码的空白体
	ctx.Redirect()   // 请求重定向
	========================================
*/

var db *xorm.Engine

func init() {
	var err error
	if db, err = xorm.NewEngine("mysql", "root:123456@/mydb?charset=utf8"); err != nil {
		log.Println(err)
	}

	// 数据表同步
	if err = db.Sync2();
		err != nil {
		log.Println(err)
	}
}

// 入口
func Run(un string) {
	e := echo.New()
	e.Use(LOGGER, CORS)
	e.Static("/", "./assets")
	e.Static("/dist", "./assets/dist")
	e.File("/", "./assets/dist/index.html")
	e.File("*", "./assets/dist/index.html")
	e.Logger.Fatal(e.Start(un))
}

// 读取用户提交
func ReadForm(ctx echo.Context, m interface{}) error {
	if err := ctx.Bind(m); err != nil {
		return ctx.JSON(500, "服务器不支持提交类型")
	}
	return nil
}

// JWT分发器
func SendJWT(data interface{}) string {
	// "Authorization":"Bearer " + JSON.parse(localStorage.getItem("token"))
	// 创建一个新的令牌对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"user": data,
		"iat":  time.Now().Unix(),                    // 发布时间
		"nbf":  time.Now().Unix(),                    // 有效起始时间
		"exp":  time.Now().Add(time.Hour * 2).Unix(), // 过期时间(2小时)
		"iss":  nil,                                  // 发行者
		"sub":  nil,                                  // 标题
		"aud":  nil,                                  // 客户(多发行者时使用)
		"jti":  nil,                                  // 唯一标识
	})
	// 设置令牌签名
	tokenString, err := token.SignedString([]byte("xxx"))
	if err != nil {
		panic(err)
	}
	return tokenString
}

// 随机字符种子
func RandomChar(l int) string {
	str := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	strs := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, strs[r.Intn(len(strs))])
	}
	return string(result)
}

var (
	/*JWT认证*/ JwtServe = middleware.JWTWithConfig(middleware.JWTConfig{
	SigningKey: []byte("xxx"),
})
	/*请求记录*/ LOGGER  = middleware.LoggerWithConfig(middleware.LoggerConfig{Format: "${time_rfc3339} [${status}] ${method} ${uri}\n"})
	/*请求跨域*/ CORS    = middleware.CORSWithConfig(middleware.CORSConfig{})
	/*程序恢复*/ Recover = middleware.RecoverWithConfig(middleware.RecoverConfig{})
	/*安全保护*/ Secure  = middleware.SecureWithConfig(middleware.SecureConfig{})
	/*防止攻击*/ CSRF    = middleware.CSRFWithConfig(middleware.CSRFConfig{})
)

// ===============================================

// 邮件分发器
var EmailServe = New(Config{
	Host:     "smtp.sina.com",
	Username: "upcyan@sina.com",
	Password: "1718408254",
	Port:     25,
})

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/1359448

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值