Go iris与webpack + vue-router + axios开发CMS

本文主要介绍的是Go iris框架与vue相关的前端构架技术,而不会涉及太多关于CMS(内容管理系统)业务。Go语言是一门非常优雅的语言,Go iris继承与扩充了Go web核心库,vue是一个非常不错的前端框架,把最好的后端与最好的前端框架融合到一起做一个CMS是一种怎样的体验呢?

在开始之前,我要先告诉大家一个好消息,本文的所有代码都可以在github上面获得,所以我在文章里面只会大纲式的介绍Go iris框架,vue,webpack,它可能不是一个入门的教材,你可能得有点前端构建的基础,github地址:https://github.com/iissy/goweb,获取上面的源码。

1. 前端开发环境搭建
a). Node.js安装
从官方网站下载Node.js的LTS版(长期支持版),地址:https://nodejs.org/en/,安装完成,它也就自动安装了node,npm等命令

b). npm包安装
npm install axios clean-webpack-plugin copy-webpack-plugin css-loader html-webpack-plugin jquery qs raw-loader style-loader vue vue-html5-editor vue-loader vue-router vue-style-loader vue-template-compiler vuex webpack webpack-cli webpack-merge --save-dev

2. 后端开发环境搭建
a). 安装Golang包
Golang的官网访问不了,我们到中文社区网下载:https://studygolang.com/dl,它建自动配置环境变量,GOPATH需要手动配置,比如,clone我的仓库到D盘,就可以配置GOPATH到D:\github.com\goweb

b). 下载第三方包
go get -u github.com/go-sql-driver/mysql
go get -u github.com/kataras/iris
go get -u github.com/gorilla/securecookie

3. 网站结构


目录(仅列表出部分目录)  功能
/private 这个目录存放的是前端打包构建的文件,包含主要包含vue模版文件,它并不对外访问,发布的时候,这个目录无需复制到服务器
/private/router 前端路由
/private/util 上传图片的脚本,时间转换,ajax请求脚本等辅助函数
/public 所有的样式文件(css文件),前端脚本,网站小图标,上传的图片,打包生成的js文件都存放在这个目录
/src go代码的存放目录
/src/access 数据层go代码
/src/cache 缓存层代码
/src/controller 处理器代码
/views go语言的视图模版

4. 路由
前端使用的是vue-router,如果没有后端的支持,它在强制刷新将丢失,Go iris提供了路径路由,可以完美的支持单页面开发路由,我们仅仅将/main/*格式的路由都指向同一个处理器controller.BasicAuth(controller.Webpack),BasicAuth负责认证,而Webpack是一个处理器:

app.Get("/main/{action:path}", controller.BasicAuth(controller.Webpack))

这个路由可以匹配下面的地址:
http://localhost/main/index
http://localhost/main/article/add
http://localhost/main/article/15/1
http://localhost/main/account/15/1
与前端的路由遥相呼应
{
path: '/main/article/add',
meta: { title: "添加文章" },
component: ArticleAdd
}, {
path: '/main/article/edit/:id',
meta: { title: "编辑文章" },
name: 'ArticleEdit',
component: ArticleAdd
}, {
path: '/main/article/:size/:pageno',
meta: { title: "文章管理" },
name: 'ArticleList',
component: ArticleList
}, {
path: '/main/account/:size/:pageno',
meta: { title: "用户列表" },
name: 'AccountList',
component: AccountList
}

再看看Go iris的分组路由
    article := app.Party("article")
    {
        article.Post("/post", controller.BasicAuth(controller.Postarticle))
        article.Post("/list/{size}/{page}", controller.BasicAuth(controller.Articlelist))
        article.Get("/get/{id}", controller.BasicAuth(controller.Getarticle))
        article.Get("/delete/{id}", controller.BasicAuth(controller.Delarticle))
    }
上面的路由分别匹配下面地址:
http://localhost/article/post
http://localhost/article/list/15/1
http://localhost/article/get/go-start
http://localhost/article/delete/go-start

github对应代码:https://github.com/iissy/goweb/blob/master/main.go

5. 缓存
var memo *cache.Memo

func init() {
    memo = cache.New(roleGetFunction)
    return
}

// 根据角色获取所有权限
func roleGetFunction(roleid int) ([]string, error) {
    funclist, err := access.GetFunctionNames(roleid)
    return funclist, err
}

// BasicAuth 是登录认证,用户分权限管理
func BasicAuth(h context.Handler) context.Handler {
    return func(ctx iris.Context) {
        if ok := utils.Check(ctx); ok {
            name := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
            index := strings.LastIndex(name, ".")
            name = strings.ToLower(name[index+1:])

            log.Print(name)
            _, roleid, _ := utils.GetUser(ctx)
            funclist, err := memo.Get(roleid)
            if err != nil {
                log.Print(err)
            }

            flag := false
            for _, item := range funclist {
                if item == name {
                    flag = true
                    break
                }
            }

            if flag {
                h(ctx)
            } else {
                ctx.JSON(models.Author{Success: false, Message: "没有权限"})
            }
        } else {
            http.Error(ctx.ResponseWriter(), http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
        }
    }
}

funclist, err := memo.Get(roleid),在这里根据用户的角色获取对应的权限,如果缓存里面有就从缓存里面拿,如果缓存没有就从数据库拿,并缓存。

github对应代码:https://github.com/iissy/goweb/blob/master/src/iissy.com/controller/auth.go

缓存话题详细介绍可以参考之前的文章:https://www.hrefs.cn/article/duplicate-suppression-in-caching-with-go-chan

6. 认证加密
我们采用的是cookie认证,然后再分权限访问,而cookie做了双重加密处理,一层是每个cookie加密,二层是token对称加密

github对应代码:https://github.com/iissy/goweb/blob/master/src/iissy.com/controller/auth.go

加密话题的详细介绍可以参考之前的文章:https://www.hrefs.cn/article/go-iris-use-securecookie

7. 中间件
go iris提供功能强大的中间件支持,比如全局的前置处理器,这里用来判断用户是否登录,同时拿取用户昵称

app.UseGlobal(controller.Before)

// Before 前置控制器
func Before(ctx iris.Context) {
    id, _, username := utils.GetUser(ctx)
    ctx.ViewData("islogin", id > 0)
    ctx.ViewData("username", username)
    ctx.Next()
}

前台展示


后台管理


总结:在使用Go iris + vue + webpack开发CMS的过程中,几乎没有遇到辣手的问题,所有的问题都能非常优雅的解决,这是一次愉快的体验,希望你也有一样的感受。
Posted by 何敏 on 2019/04/09 03:48:37