Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

172 lines (140 sloc) 4.5 KB
// file: controllers/user_controller.go
package controllers
import (
"github.com/kataras/iris/_examples/mvc/login/datamodels"
"github.com/kataras/iris/_examples/mvc/login/services"
"github.com/kataras/iris"
"github.com/kataras/iris/mvc"
"github.com/kataras/iris/sessions"
)
// UserController is our /user controller.
// UserController is responsible to handle the following requests:
// GET /user/register
// POST /user/register
// GET /user/login
// POST /user/login
// GET /user/me
// All HTTP Methods /user/logout
type UserController struct {
// context is auto-binded by Iris on each request,
// remember that on each incoming request iris creates a new UserController each time,
// so all fields are request-scoped by-default, only dependency injection is able to set
// custom fields like the Service which is the same for all requests (static binding)
// and the Session which depends on the current context (dynamic binding).
Ctx iris.Context
// Our UserService, it's an interface which
// is binded from the main application.
Service services.UserService
// Session, binded using dependency injection from the main.go.
Session *sessions.Session
}
const userIDKey = "UserID"
func (c *UserController) getCurrentUserID() int64 {
userID := c.Session.GetInt64Default(userIDKey, 0)
return userID
}
func (c *UserController) isLoggedIn() bool {
return c.getCurrentUserID() > 0
}
func (c *UserController) logout() {
c.Session.Destroy()
}
var registerStaticView = mvc.View{
Name: "user/register.html",
Data: iris.Map{"Title": "User Registration"},
}
// GetRegister handles GET: http://localhost:8080/user/register.
func (c *UserController) GetRegister() mvc.Result {
if c.isLoggedIn() {
c.logout()
}
return registerStaticView
}
// PostRegister handles POST: http://localhost:8080/user/register.
func (c *UserController) PostRegister() mvc.Result {
// get firstname, username and password from the form.
var (
firstname = c.Ctx.FormValue("firstname")
username = c.Ctx.FormValue("username")
password = c.Ctx.FormValue("password")
)
// create the new user, the password will be hashed by the service.
u, err := c.Service.Create(password, datamodels.User{
Username: username,
Firstname: firstname,
})
// set the user's id to this session even if err != nil,
// the zero id doesn't matters because .getCurrentUserID() checks for that.
// If err != nil then it will be shown, see below on mvc.Response.Err: err.
c.Session.Set(userIDKey, u.ID)
return mvc.Response{
// if not nil then this error will be shown instead.
Err: err,
// redirect to /user/me.
Path: "/user/me",
// When redirecting from POST to GET request you -should- use this HTTP status code,
// however there're some (complicated) alternatives if you
// search online or even the HTTP RFC.
// Status "See Other" RFC 7231, however iris can automatically fix that
// but it's good to know you can set a custom code;
// Code: 303,
}
}
var loginStaticView = mvc.View{
Name: "user/login.html",
Data: iris.Map{"Title": "User Login"},
}
// GetLogin handles GET: http://localhost:8080/user/login.
func (c *UserController) GetLogin() mvc.Result {
if c.isLoggedIn() {
// if it's already logged in then destroy the previous session.
c.logout()
}
return loginStaticView
}
// PostLogin handles POST: http://localhost:8080/user/register.
func (c *UserController) PostLogin() mvc.Result {
var (
username = c.Ctx.FormValue("username")
password = c.Ctx.FormValue("password")
)
u, found := c.Service.GetByUsernameAndPassword(username, password)
if !found {
return mvc.Response{
Path: "/user/register",
}
}
c.Session.Set(userIDKey, u.ID)
return mvc.Response{
Path: "/user/me",
}
}
// GetMe handles GET: http://localhost:8080/user/me.
func (c *UserController) GetMe() mvc.Result {
if !c.isLoggedIn() {
// if it's not logged in then redirect user to the login page.
return mvc.Response{Path: "/user/login"}
}
u, found := c.Service.GetByID(c.getCurrentUserID())
if !found {
// if the session exists but for some reason the user doesn't exist in the "database"
// then logout and re-execute the function, it will redirect the client to the
// /user/login page.
c.logout()
return c.GetMe()
}
return mvc.View{
Name: "user/me.html",
Data: iris.Map{
"Title": "Profile of " + u.Username,
"User": u,
},
}
}
// AnyLogout handles All/Any HTTP Methods for: http://localhost:8080/user/logout.
func (c *UserController) AnyLogout() {
if c.isLoggedIn() {
c.logout()
}
c.Ctx.Redirect("/user/login")
}
You can’t perform that action at this time.