退出登录
我们上一节实现了用户登录。在这一节中,我们首先实现用户退出登录的功能。
因为退出登录的代码不需要做任何与数据库的交互,所以我们会直接将这些代码写在控制器中,而不是写在模型中。
首先,我们还是来编写测试代码。向users_controller_test.go中添加一个TestLogout()函数。
代码清单4-1
users_controller_test.go
.
.
.
func TestUserLogout(t *testing.T) {
app := iris.New()
ctx := context.NewContext(app)
setCtxResponse(ctx)
setCtxRequest(ctx, nil, 0)
controller := UsersController{}
setSession(ctx, &controller)
// 测试用户未登录时调用UersController#Logout()
err := controller.Logout()
if err.Error() != "not logged in" {
t.Errorf("expected get "not logged in" but got "%s"n", err.Error())
}
// 测试用户登录后调用UersController#Logout()
controller.Session.Set("userID", 1)
err = controller.Logout()
userID, _ := controller.Session.GetInt("userID")
if userID >= 0 {
t.Errorf("expected user id in session to be -1 but got %dn", userID)
}
if err != nil {
t.Error("got an error:", err)
}
}
这份测试代码中,为了对已有的代码进行精简,我们将上一节中的一部分代码替换为了下面三个函数:
代码清单4-2
users_controller_test.go
func setCtxRequest(ctx iris.Context, body io.ReadCloser, contentLength int64) {
newRequest, _ := http.NewRequest("FAKEMETHOD", "/fake_path", nil)
newRequest.Body = body
newRequest.ContentLength = contentLength
ctx.ResetRequest(newRequest)
}
func setCtxResponse(ctx iris.Context) {
w := context.AcquireResponseWriter()
hw := httptest.NewRecorder()
w.BeginResponse(hw)
ctx.ResetResponseWriter(w)
}
func setSession(ctx iris.Context, controller *UsersController) {
cookie := http.Cookie{
Name: "sample_cookie_uuid", Value: ""}
ctx.SetCookie(&cookie)
sess := sessions.New(sessions.Config{
Cookie: "weibo_app_cookie", Expires: 120000000000})
controller.Session = sess.Start(ctx)
}
接下来,我们可以来正式编写代码了。
代码清单4-3
controllers/users_controller.go
.
.
.
func (c *UsersController) BeforeActivation(b mvc.BeforeActivation) {
middleware := func(ctx iris.Context) {
ctx.Application().Logger()
ctx.Next()
}
b.Handle("POST", "/users/new", "Create", middleware)
b.Handle("GET", "/users/{id:int}", "Show", middleware)
b.Handle("POST", "/login", "Login", middleware)
b.Handle("DELETE", "/logout", "Logout", middleware)
}
.
.
.
func (c *UsersController) Logout() (err error) {
if !IsLoggedIn(c.Session) {
err = errors.New("not logged in")
return
}
if !c.Session.Delete("userID") {
err = errors.New("logout failed. please try again later")
}
return
}
退出登录的代码很简单,我们首先检查了用户是否确实已经登录,在保证用户确实已经登录的情况下,我们才从session中删去userID的值。否则我们会返回一个错误提示用户尚未登录。
在这里,我们用