Skip to content

Latest commit

 

History

History
264 lines (196 loc) · 7.95 KB

File metadata and controls

264 lines (196 loc) · 7.95 KB

14.4 User validation

In the process of developing Web applications, user authentication is frequently encountered problems developers, user log in, registration, log out and other operations, and the general certification is also divided into three aspects of certification

  • HTTP Basic and HTTP Digest Authentication
  • Third Party Certified Integration: QQ, micro-blogging, watercress, OPENID, Google, GitHub, Facebook and twitter, etc.
  • Custom user log in, registration, log out, are generally based on session, cookie authentication

beego There is no way for any of these three forms of integration, but can make use of third party open source library to achieve the above three methods of user authentication, but the first two subsequent authentication beego be gradually integrated.

HTTP basic and digest authentication

These two certifications are some applications using relatively simple authentication, there are already open source third-party library supports both authentication:

github.com/abbot/go-http-auth

The following code demonstrates how to use this library in order to achieve the introduction of beego Certification:

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"] = "[email protected]"
	this.TplNames = "index.tpl"
}

The above code takes advantage of beego the prepare function in the normal logic function is called before the certification, so it is very simple to achieve a http auth, digest authentication is the same principle.

OAuth and OAuth 2 certification

OAuth and OAuth 2 is currently more popular two authentication methods, but fortunately, there is a third-party library to achieve this certification, but it is realized abroad, and did not QQ, microblogging like domestic application certified integration:

github.com/bradrydzewski/go.auth

The following code demonstrates how to put the library in order to achieve the introduction of beego OAuth authentication, an example to demonstrate GitHub here:

  1. Add two routes

     beego.RegisterController("/auth/login", &controllers.GithubController{})
     beego.RegisterController("/mainpage", &controllers.PageController{})
  2. Then we deal GithubController landing page:

     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. treatment after successful landing pages

     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"
     }

The whole process is as follows, first open your browser and enter the address:

Figure 14.4 shows the home page with a log in button

Then click on the link following screen appears:

Figure 14.5 is displayed after clicking the log in button authorization GitHub page

Then click Authorize app will appear the following interface:

Figure 14.6 is displayed after log in authorization to obtain information page GitHub

Custom authentication

Custom authentication and session are generally a combination of proven, the following code from an open source based beego blog:

//Login process
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)

		//Set the session successful login
		sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request)
		sess.Set("uid", userInfo.Id)
		sess.Set("uname", userInfo.Username)

		this.Ctx.Redirect(302, "/")
	}	
}

//Registration process
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)

		//Set the session successful login
		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
}

With the user log in and registration, where you can add other modules such as the judgment of whether the user log in:

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