上一篇把Shiro部署到Grails上了,并且可以正常运行,虽然可以使用grails generate-all domain方式生成CRUD的脚手架增加用户或角色,但是出于业务的角度考虑,我们不希望所有人都可以增加用户信息,所以,我们新增加一个注册的功能,供没有账号的人注册自己的个人资料,而有admin权限的人可以登录到系统使用CRUD去维护这些账户信息。
注册
- 现在创建一个SignupController,用来处理注册过程
$grails create-controller com.example.SignupController
- 在Controller中增加注册方法
1 package com.example 2 3 import org.apache.shiro.authc.UsernamePasswordToken 4 import org.apache.shiro.SecurityUtils 5 6 class SignupController { 7 def shiroSecurityService 8 9 def index() { 10 User user = new User() 11 [user: user] 12 } 13 14 def register() { 15 // Check to see if the username already exists 16 def user = User.findByUsername(params.username) 17 if (user) { 18 flash.message = "User already exists with the username '${params.username}'" 19 redirect(action:'index') 20 } else { // User doesn't exist with username. Let's create one 21 // Make sure the passwords match 22 if (params.password != params.password2) { 23 flash.message = "Passwords do not match" 24 redirect(action:'index') 25 } else { // Passwords match. Let's attempt to save the user 26 // Create user 27 user = new User(username: params.username,passwordHash: shiroSecurityService.encodePassword(params.password)) 28 29 if (user.save()) { 30 // Add USER role to new user 31 user.addToRoles(Role.findByName('ROLE_USER')) 32 // Login user 33 def authToken = new UsernamePasswordToken(user.username, params.password) 34 SecurityUtils.subject.login(authToken) 35 36 redirect(controller: 'home', action: 'secured') 37 }else {} 38 } 39 } 40 } 41 }
- 在这个Controller中定义了index和register两个action
- index action用来显示注册界面
- register action处理注册结果,如果注册成功则redirect到HomeController下的secured action
下面增加一个index.gsp界面,当访问http://localhost:8080/shiro-example/home/index时跳转到注册界面
1 <%@ page contentType="text/html;charset=UTF-8"%> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 5 <title>Register</title> 6 <meta name="layout" content="main" /> 7 </head> 8 9 <body> 10 <h1>Signup</h1> 11 <g:if test="${flash.message}"> 12 <div class="alert alert-info">${flash.message}</div> 13 </g:if> 14 <g:hasErrors bean="${user}"> 15 <div class="alert alert-error"><g:renderErrors bean="${user}" as="list" /></div> 16 </g:hasErrors> 17 18 <g:form action="register"> 19 <fieldset class="form"><g:render template="register"/></fieldset> 20 21 <fieldset class="buttons"> 22 <g:submitButton name="submit" value="Submit"/> 23 </fieldset> 24 </g:form> 25 26 </body> 27 </html>
在这里,使用<g:render template="register"/>引用了一个register模板,grails会去view下的当前gsp文件的相同目录中去找_register.gsp文件。所以,再建一个_register.gsp文件,定义表单内容
1 <%@ page import="com.example.User" %> 2 3 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'username', 'error')} required"> 4 <label for="username"> 5 <g:message code="user.username.label" default="Username" /> 6 <span class="required-indicator">*</span> 7 </label> 8 <g:textField name="username" required="" value="${userInstance?.username}"/> 9 </div> 10 11 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'passwordHash', 'error')} required"> 12 <label for="password">Password</label> 13 <span class="required-indicator">*</span> 14 <g:passwordField name="password" value=""/> 15 </div> 16 17 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'passwordHash', 'error')} required"> 18 <label for="password">Confirm Password</label> 19 <span class="required-indicator">*</span> 20 <g:passwordField name="password2" value=""/> 21 </div>
- 现在访问http://localhost:8080/shiro-example/signup,系统跳转到signup/index注册页面,登记注册信息
- 正常完成后跳转到http://localhost:8080/shiro-example/home/secured,一切正常