grails 的登陆 退出 过滤

1、  现在我们需要为系统设计一个登录页面,使得访问任何需要登录的页面时都会呈现以下页面:

                       

只有当用户登录成功后,才会跳转到先前要访问的页面。

2、  新建域类LoginUser:

LoginUser用于保存登录用户的相关信息,比如帐号和密码。

class LoginUser {//域:登陆用户

    static constraints = {

userId(length:6..8,unique:true)//帐号6-8位

password(length:6..8)//密码6-8位

name(nullable:false)//姓名不可为空

level(range:1..10)//用户级别分10级,够了吧?

    }

    String userId//用户名

    String password//密码

    String name//用户姓名

    int level//用户权限级别

}

 

3、  为系统配置一个默认的系统管理员:

打开grails-app/conf/BootStrap.groovy,编辑init闭包(我们可以利用init闭包在系统一启动时做一些初始化的工作):

     def init = { servletContext ->

     final String BACK_ADMIN='admin'

     if(!LoginUser.findByUserId(BACK_ADMIN)){

     new LoginUser(userId:BACK_ADMIN,password:'admin88',name:'\u7BA1\u7406\u5458',level:10).save()

     }

     }

这样,只要系统一启动,就会自动添加admin用户,这样无论系统中有没有录入一个用户,我们都有一个admin的管理员帐号可用。

4、  新建登陆页面:

编辑grails-app/views/loginUser/login.gsp:

 

<g:form action="login"   method="post" >

 

……

 

<input type="text"   id="userId" name="userId" value="${loginUserInstance?.userId}" maxlength="8"/>

//用户名输入框

……

 

<input type="password"   id="password" name="password" maxlength="8"/>

//密码输入框

……

 

<input class="button"   type="submit" value="登录" />

//若使用<g:submitButton>标签可能无法正常提交,原因不知

……

 

</g:form>

 

5、  在loginuser控制器中定义登录/注销action

打开grails-app/controllers/LoginUserController.groovy:

def login={

//action:登录

if(request.method=='GET'){//清除session

//若请求方式为get,呈现login.gsp

session.userId=null

 

session.level=null

 

def loginUserInstance=new LoginUser()

//定义一个空的LoginUser实例

}else{

//若请求参数为表单提交

def loginUserInstance=LoginUser.findByUserIdAndPassword(

//从根据用户名密码查找已有的用户

params.userId,params.password)

 

if(loginUserInstance){//添加session

//若找到匹配的用户,进行登录

session.userId=params.userId

//把用户名记入session

session.level=loginUserInstance.level

//把用户级别记入session

def requestParams=session.originReqParams?session.originReqParams:[controller:'loginUser',action:'login']

//从session中取用户先前请求的控制器和action

redirect(requestParams)

//登录成功,转入用户先前请求的页面

}else{//登录帐号或密码错误

//若找不到匹配用户,登录失败

flash['message']='\u767B\u5F55\u5E10\u53F7\u6216\u5BC6\u7801\u9519\u8BEF'

//显示登录失败信息

}}}

//如果前面都没有转向,则这里呈现默认视图——登录页面login.gsp

def logout={

//action:注销

session.userId=null

//从session中删除用户名

session.level=null

//从session中删除用户级别

flash['message']='\u6210\u529F\u9000\u51FA\u767B\u5F55' //成功退出登录

//显示成功注销消息

    redirect(controller:'loginUser',action:'login')         //转向登录页

//转向登录页面

}

 

6、  定义拦截器

我们的要求是系统必须在用户登录后才能访问,用户未登录情况下,只能显示登录页面login.gsp。

这样我们需要一个拦截器,在任何action被处理之前,先处理拦截器指定的内容,比如登录。如果登录成功,返回true,则该action接下来被正常处理,否则返回false,接下来该action的处理被忽略。

由于基本上,所有的控制器都需要一个拦截器,而且这些拦截器需要进行的处理都差不多——都强制要求用户进行登录,所以我们先来定义一个基类BaseController。在这个基类中我们定义好所有拦截器都需要进行的处理,然后让所有的控制器来继承它就可以了。

运行create-controller Base,然后编辑BaseController.groovy:

class BaseController {

    def auth(){                  //定义一个 auth 方法

    if(!session.userId){        //如果在session中找不到用户id-即未登录

//定义一个map对象

def originReqParams=[controller:controllerName,action:actionName]

originReqParams.putAll(params)  //把用户此时请求的控制器和action放入map对象

session.originReqParams=originReqParams//把map放入session方便下次转向

redirect(controller:'loginUser',action:'login')//调用登录页面要求用户登录

return false      //返回false,则忽略用户原先请求的action

    }   }}

然后让所有的控制器都继承BaseController。这样所有的控制器都有一个叫auth的方法可用了。

在所有的控制器中加入:

def beforeInterceptor = [action:this.&auth]

这定义了一个简单的前置拦截器(即在action被处理之前触发)。它简单的要求所有的action被处理之前,先调用auth方法(注意这里使用了指针语法&符号)。

此外,在loginUser控制器中加入拦截器的是:

def beforeInterceptor=[action:this.&auth,except:['login']]

当然,这个拦截器在拦截action时,把login排除在外(因为对用户的登录动作要求行强制的登录本身就是多余的)。

 

现在,我们可以尝试访问所有的controller和action,如果我们没有事先登录,则所有的请求都会转到登录页面。只有当我们输入用户名密码进行登录之后,才会转入我们要访问的action。

7、   由于我们要求用户一开始访问系统时,显示的就是产品编号列表,则我们应该修改系统首页:

打开grails-app/views/index.gsp,在其中加入:

<%

response.sendRedirect(request.getContextPath()+"/productionNo/index");

%>

则当用户访问http://localhost:8080/IronwareProcess这个地址看到的将是登录页面,等用户登录后,才显示产品编号列表:

 

posted @ 2015-10-24 23:08  mxyhws  阅读(379)  评论(0编辑  收藏  举报