We have already initialized the blog system, then we will do the administrator login and permission control judgment. We will introduce login control using sessions and cookies separately.

The use of the sessions

Earlier we used sessions in the middleware session and gave a brief introduction. We’ll elaborate here on how sessions are used.

Use session, the need to introduce github.com/kataras/iris/v12/sessions, this is a sessions manager. We need to use it to store session data. Let’s look at how it stores session data.

We need to initialize sessions in the project:

var Sess = sessions.New(sessions.Config{Cookie: "irisweb"})
Copy the code

Start(CTX). The Start function needs to receive a context. Then we define a field hasLogin to store the login status. We inject hasLogin into the context using the ctx.values ().set () method so that subsequent controllers can judge and check the call. We do not intercept exit operations in the middleware step.

func Auth(ctx iris.Context) {
	// Check the login status
	session := Sess.Start(ctx)
	hasLogin := session.GetBooleanDefault("hasLogin".false)
	ctx.Values().Set("hasLogin", hasLogin)
	ctx.ViewData("hasLogin", hasLogin)

	ctx.Next()
}
Copy the code

Administrator Login

To log in as a blog administrator, you must first have a page to log in to and a controller to handle the login.

Administrator Login page

Create an admin folder in the template folder and create a new login.html inside:

{% include "partial/header.html" %}
<div class="admin-login">
    <div class="login-main">
        <div class="login-box login-header">
            <h2>{{SiteName}}</h2>
            <p>A simple blogging system written by the IRisWeb framework</p>
        </div>
        <div class="login-box login-body layui-form">
            <div class="layui-form-item">
                <label class="login-icon layui-icon layui-icon-username" for="login-username"></label>
                <input type="text" name="user_name" id="login-username" lay-verify="required" placeholder="Username" class="layui-input">
            </div>
            <div class="layui-form-item">
                <label class="login-icon layui-icon layui-icon-password" for="login-password"></label>
                <input type="password" name="password" id="login-password" lay-verify="required" placeholder="Password" class="layui-input">
            </div>
            <div class="layui-form-item">
                <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="login-submit">Log in</button>
            </div>
        </div>
    </div>

    {% include "partial/footer.html" %}
</div>
Copy the code

Above is the HTML code for the login page, and again, we have introduced the header and tail snippets. The administrator login form contains two fields, the administrator username (user_name) and the administrator password (password), which are both required fields. For the sake of simplicity, the verification part of the verification code is not included here. If you are a little more serious, you need to add a captcha here.

Submitting the form is JS code

Open the public/static/js/app.js file and add the js code to listen for the login button:

form.on('submit(login-submit)'.function(obj){
		$.post('/admin/login', obj.field, function(res) {
				if(res.code === 0) {
						layer.msg('Login successful', {
								offset: '15px'
								,icon: 1
								,time: 1000
						}, function(){
								window.location.href = '/';
						});
				} else{ layer.msg(res.msg); }}); });Copy the code

After a user clicks the login button (even after the user enters the input key and presses Enter), request /admin/login by POST. If res.code is 0 in the returned RES information, the login is successful and the home page is redirected. Otherwise, an error message will be displayed.

Administrator The controller on the login page

Next, in the Controller directory, we create an admin.go file to hold the controller for the login page and the controller for the login process. Add AdminLogin() to it:

func AdminLogin(ctx iris.Context) {

	ctx.View("admin/login.html")}Copy the code

This controller is simple and only needs to host the login page.

The administrator logs in to process the logical controller

Next, we need to create a system that accepts the information submitted by the login page to complete the login process.

Let’s start by defining a structure that receives login information. In the Request folder, create a new admin. go file and add the following code:

package request

type Admin struct {
	UserName string `form:"user_name" validate:"required"`
	Password string `form:"password" validate:"required"`
}
Copy the code

Only two fields are submitted in the login form, UserName and Password, which are mandatory fields.

Next, we write the logon handler logic controller. In the controller/admin.go file, add the AdminLoginForm() function:

func AdminLoginForm(ctx iris.Context) {
	var req request.Admin
	iferr := ctx.ReadForm(&req); err ! =nil {
		ctx.JSON(iris.Map{
			"code": config.StatusFailed,
			"msg":  err.Error(),
		})
		return
	}

	admin, err := provider.GetAdminByUserName(req.UserName)
	iferr ! =nil {
		ctx.JSON(iris.Map{
			"code": config.StatusFailed,
			"msg":  err.Error(),
		})
		return
	}

	if! admin.CheckPassword(req.Password) { ctx.JSON(iris.Map{"code": config.StatusFailed,
			"msg":  "Login failed",})return
	}

	session := middleware.Sess.Start(ctx)
	session.Set("hasLogin".true)

	ctx.JSON(iris.Map{
		"code": 0."msg":  "Login successful"."data": 1})},Copy the code

This function reads the form information submitted by the front end into the request.Admin structure via ctx.ReadForm, and prints a JSON error message if it reads incorrectly.

The administrator is then checked for the existence of the database by the user name, and an error is returned if the user name is incorrect.

If all the previous checks are correct, use CheckPassword() to check whether the entered password is correct. Model /admin.go:

func (admin *Admin) CheckPassword(password string) bool {
	if password == "" {
		return false
	}

	byteHash := []byte(admin.Password)
	bytePass := []byte(password)
	err := bcrypt.CompareHashAndPassword(byteHash, bytePass)
	iferr ! =nil {
		return false
	}

	return true
}
Copy the code

The CheckPassword() function is a built-in method of the Admin model that takes a password argument, By golang.org/x/crypto/bcrypt packet bcrypt.Com pareHashAndPassword the bcrypt hash () function to verify the admin Password admin, Password and Password of the incoming text passwords are equivalent, Returns zero on success and error on failure. We determine if an error is nil, if there’s an error, it’s failure, return false, and the rest return true.

After successfully verifying the password, we use the sessions memory Sess declared by the middleware to set the login status:

  session := middleware.Sess.Start(ctx)
	session.Set("hasLogin".true)
Copy the code

Logging Out of the Controller

Now that we have logged in, we also need to log out. To do this, add AdminLogout() in Controller /admin.go.

func AdminLogout(ctx iris.Context) {
	session := middleware.Sess.Start(ctx)
	session.Delete("hasLogin")

	ctx.Redirect("/")}Copy the code

To log out of the controller, there is no need to have a front end page. We just need to remove hasLogin marked in sessions. To remove a session, we use session.delete (), which accepts the session field to be removed. After logging out, we jumped back to the home page.

Configuring a Login Route

The controller associated with the login page and logon processing logic above is written, and we need to inject it into the route before it can be accessed from the browser. We now open the route/base.go file and add three routes to Register:

  admin := app.Party("/admin", controller.Inspect)
	{
		admin.Get("/login", controller.AdminLogin)
		admin.Post("/login", controller.AdminLoginForm)
		admin.Get("/logout", controller.AdminLogout)
	}
Copy the code

Here, since /admin is a path prefix, paths that start with admin are paths that handle logins, so we use app.party () to categorize them as a routing group. There are even more complex functions available, such as binding it to a secondary domain name. For the sake of brevity, we will not use the secondary domain name operation.

The verification results

Let’s restart the project and access it in the browserhttp://127.0.0.1:8001/admin/loginTo see the effect, verify that the login process is normal. If nothing goes wrong, you’ll see something like this:Enter the correct account and password to complete the login.

The complete project sample code is hosted on GitHub. The complete project code can be viewed at github.com/fesiong/gob… You can also fork a copy to make changes on it.