Click here to see a very basic login application with hard-coded user credentials. In current article I am discussing as on how to validate from a table where login id and password is stored. The article above points to the usage of flash and session's uses. I will not discuss more about flash and session in this article.
My assumption is that a person is assigned for a login with his email id. Based on that I planned for a domain called "Person" as below (I named the application happy):
package happy
class Person {
String firstName
String lastName
String emailID
String loginPassword
Boolean superUser
static constraints = {
firstName(size:1..120,nullable:false,blank:false)
lastName(size:1..120,nullable:false,blank:false)
emailID(email:true,size:1..120,nullable:false,blank:false)
loginPassword(password:true,size:6..20,nullable:false,blank:false)
}
}
class Person {
String firstName
String lastName
String emailID
String loginPassword
Boolean superUser
static constraints = {
firstName(size:1..120,nullable:false,blank:false)
lastName(size:1..120,nullable:false,blank:false)
emailID(email:true,size:1..120,nullable:false,blank:false)
loginPassword(password:true,size:6..20,nullable:false,blank:false)
}
}
In my PersonController.groovy, I added an interceptor which should validate a session. If no session is available it should redirect me to login page.
package happy
class PersonController {
def beforeInterceptor = [action.this.&checkUser]
static scaffold = true
def checkUser() {
if(!session.user) {
redirect(controller:'person',action:'login')
flash.message = "Invalid Username/Password, please try again."
}
}
}
I have successfully added a validation for all controllers in Person. If there is no login detected the user should be redirected to a login page. Next part is to design that page.
def login = {
}
I have put a blank controller inside the Person controller for login. Now I have to create a gsp file for this controller to successfully work. For this, I copied the index.gsp from views folder and copied it as login.gsp inside person foler within views. I deleted the entire contents within body tag and replaced with the following code:
<body>
<a href="#page-body" class="skip">
<g:message code="default.link.skip.label" default="Skip to content…"/></a>
<g:render template="loginHeader"/>
<div class="bodyContent" id="bodyContent">
<g:if test="${flash.message}">
<div class="message">${flash.message}
</div>
</g:if>
</div>
</body>
It is a simple code, please read through all lines. From <g:render> tag, I will explain. It is looking for a _loginHeader.gsp as its a template. It then displays the body content and if any messages.
The following are the contents of _loginHeader.gsp located in views/person folder.
<g:if test="${session.user}">
<div class="login">
<g:remoteLink controller="person" action="list" update="bodyContent">${session.user.emailID}</g:remoteLink> | <g:link action="logout">Logout</g:link>
</div>
</g:if>
<g:else>
<g:form action="doLogin" method="post">
<div class="login">
<label for='emailID'>Email ID</label>
<input id="emailID" required type='text' name='emailID' value='${person?.emailID}' />
<label for='loginPassword'>Password</label>
<input id="loginPassword" required type='password' name='loginPassword' value='${person?.loginPassword}' />
<input type="submit" value="Login"></input>
</div>
</g:form>
</g:else>
This page will be used across all pages, that is why I decided to create it as a template. It checks for a session, and if found it displays the person logged in or else displays the login input boxes.
The form which has the input boxes for email ID and password are submitting to a doLogin. This method must be defined within the PersonController.groovy as well.
def doLogin = {
def user = Person.findWhere(emailID:params['emailID'],loginPassword:params['loginPassword'])
session.user = user
if (user){
redirect(controller:'person',action:'list')
flash.message = "Logged in as <b>$user.firstName $user.lastName ($user.emailID)</b>"
}else{
redirect(controller:'person',action:'login')
flash.message = "Invalid Username/Password, please try again."
}
}
Download Application Note: The application uses Grails 2