diff --git a/14.4.md b/14.4.md index a11457d2..13a68c1b 100644 --- a/14.4.md +++ b/14.4.md @@ -14,6 +14,39 @@ beego目前没有针对这三种方式进行任何形式的集成,但是可以 下面代码演示了如何把这个库引入beego中从而实现认证: + package controllers + + import ( + "github.com/abbot/go-http-auth" + "github.com/astaxie/beego" + ) + + func Secret(user, realm string) string { + if user == "john" { + // password is "hello" + return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" + } + return "" + } + + type MainController struct { + beego.Controller + } + + func (this *MainController) Prepare() { + a := auth.NewBasicAuthenticator("example.com", Secret) + if username := a.CheckAuth(this.Ctx.Request); username == "" { + a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) + } + } + + func (this *MainController) Get() { + this.Data["Username"] = "astaxie" + this.Data["Email"] = "astaxie@gmail.com" + this.TplNames = "index.tpl" + } + +上面代码利用了beego的prepare函数,在执行之前调用了认证函数,我们可以看到非常容易的就实现了http auth,digest的认证也是同样的原理。 ## oauth和oauth2的认证 oauth和oauth2是目前比较流行的两种认证方式,还好第三方有一个库实现了这个认证,但是是国外实现的,没有QQ、微博之类的国内应用认证集成: @@ -22,9 +55,196 @@ oauth和oauth2是目前比较流行的两种认证方式,还好第三方有一 下面代码演示了如何把该库引入beego中从而实现oauth的认证,这里以github为例演示: - +1. 添加两条路由 + beego.RegisterController("/auth/login", &controllers.GithubController{}) + beego.RegisterController("/mainpage", &controllers.PageController{}) + +2. 然后我们处理GithubController登陆的页面: + + package controllers + + import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + ) + + const ( + githubClientKey = "a0864ea791ce7e7bd0df" + githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" + ) + + type GithubController struct { + beego.Controller + } + + func (this *GithubController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + githubHandler := auth.Github(githubClientKey, githubSecretKey) + + githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) + } + + +3. 处理登陆成功之后的页面 + + package controllers + + import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + "net/http" + "net/url" + ) + + type PageController struct { + beego.Controller + } + + func (this *PageController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + user, err := auth.GetUserCookie(this.Ctx.Request) + + //if no active user session then authorize user + if err != nil || user.Id() == "" { + http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) + return + } + + //else, add the user to the URL and continue + this.Ctx.Request.URL.User = url.User(user.Id()) + this.Data["pic"] = user.Picture() + this.Data["id"] = user.Id() + this.Data["name"] = user.Name() + this.TplNames = "home.tpl" + } + +整个的流程如下,首先打开浏览器输入地址: + +![](images/14.4.github.png?raw=true) + +然后点击链接出现如下界面: + +![](images/14.4.github2.png?raw=true) + +然后点击Authorize app就出现如下界面: + +![](images/14.4.github3.png?raw=true) ## 自定义认证 +自定义的认证一般都是和session结合的验证的,如下代码来源于一个基于beego的开源博客: + + + //登陆处理 + func (this *LoginController) Post() { + this.TplNames = "login.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + if userInfo.Password == newPass { + var users models.User + users.Last_logintime = now + models.UpdateUserInfo(users) + + //登录成功设置session + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + + this.Ctx.Redirect(302, "/") + } + } + + //注册处理 + func (this *RegController) Post() { + this.TplNames = "reg.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + usererr := checkUsername(username) + fmt.Println(usererr) + if usererr == false { + this.Data["UsernameErr"] = "Username error, Please to again" + return + } + + passerr := checkPassword(password) + if passerr == false { + this.Data["PasswordErr"] = "Password error, Please to again" + return + } + + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + + if userInfo.Username == "" { + var users models.User + users.Username = username + users.Password = newPass + users.Created = now + users.Last_logintime = now + models.AddUser(users) + + //登录成功设置session + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + this.Ctx.Redirect(302, "/") + } else { + this.Data["UsernameErr"] = "User already exists" + } + + } + + func checkPassword(password string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { + return false + } + return true + } + + func checkUsername(username string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { + return false + } + return true + } + +有了用户登陆和注册之后,其他模块的地方可以增加如下这样的用户是否登陆的判断: + + func (this *AddBlogController) Prepare() { + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess_uid := sess.Get("userid") + sess_username := sess.Get("username") + if sess_uid == nil { + this.Ctx.Redirect(302, "/admin/login") + return + } + this.Data["Username"] = sess_username + } ## links * [目录]() diff --git a/14.7.md b/14.7.md index da52dc27..0b31a314 100644 --- a/14.7.md +++ b/14.7.md @@ -1,4 +1,5 @@ # 14.7 小结 +这一章主要阐述了如何基于beego框架进行扩展,这包括静态文件的支持,静态文件主要讲述了如何利用beego进行快速的网站开发,利用bootstrap搭建漂亮的站点,第二小结讲解了如何在beego中集成sessionManager,方便用户在利用beego的时候快速的使用session,第三小结介绍了表单和验证,基于Go语言的struct的定义使得我们在开发Web的过程中从重复的工作中解放出来,而且加入了验证之后可以尽量做到数据安全,第四小结介绍了用户认证,用户认证主要有三方面的需求,http basic和http digest认证,第三方认证,自定义认证,第三章通过代码演示了如何利用现有的第三方包实现这写认证。 ## links * [目录]() diff --git a/images/14.4.github.png b/images/14.4.github.png new file mode 100644 index 00000000..4da4c6f5 Binary files /dev/null and b/images/14.4.github.png differ diff --git a/images/14.4.github2.png b/images/14.4.github2.png new file mode 100644 index 00000000..c3ae04bf Binary files /dev/null and b/images/14.4.github2.png differ diff --git a/images/14.4.github3.png b/images/14.4.github3.png new file mode 100644 index 00000000..e98768c3 Binary files /dev/null and b/images/14.4.github3.png differ