웹사이트 검색

JSF 인증 로그인 로그아웃 데이터베이스 예제


인증 메커니즘을 통해 사용자는 사용자 이름과 암호를 확인하여 애플리케이션에 안전하게 액세스할 수 있습니다. 우리는 로그인을 위한 JSF 보기, 세션 관리를 위한 DAO 객체, HttpSession, JSF 관리 빈 및 mysql 데이터베이스를 사용할 것입니다. 이제 JSF 애플리케이션에서 JSF 로그인 로그아웃 인증 메커니즘을 생성하는 방법에 대해 자세히 살펴보겠습니다. 1단계: 다음과 같이 mysql 데이터베이스에 사용자 테이블을 생성합니다.

CREATE TABLE Users( 
uid int(20) NOT NULL AUTO_INCREMENT, 
uname VARCHAR(60) NOT NULL, 
password VARCHAR(60) NOT NULL, 
PRIMARY KEY(uid));

여기에서 uid를 기본 키로 사용하는 사용자 테이블, null 제약 조건이 없는 사용자 이름 및 암호 필드를 만듭니다. 2단계: 테이블 Users as에 데이터를 삽입합니다.

INSERT INTO Users VALUES(1,'adam','adam');
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html">
<h:head>
	<title>login</title>
</h:head>
<h:body>
	<h:form>
		<h3>JSF Login Logout</h3>
		<h:outputText value="Username" />
		<h:inputText id="username" value="#{login.user}"></h:inputText>
		<h:message for="username"></h:message>
		<br></br><br></br>
		
		<h:outputText value="Password" />
		<h:inputSecret id="password" value="#{login.pwd}"></h:inputSecret>
		<h:message for="password"></h:message>
		<br></br><br></br>
		
		<h:commandButton action="#{login.validateUsernamePassword}"
			value="Login"></h:commandButton>
	</h:form>
</h:body>
</html>

여기에서는 사용자 이름 및 암호 필드가 있는 JSF 로그인 보기 페이지를 만들고 로그인 관리 빈을 통해 이러한 필드에 대한 값을 설정합니다. 로그인 버튼을 클릭하면 validateUsernamePassword 메서드를 호출하여 사용자 이름과 암호를 확인합니다. 4단계: 관리 빈 Login.java를 다음과 같이 생성합니다.

package com.journaldev.jsf.beans;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import com.journaldev.jsf.dao.LoginDAO;
import com.journaldev.jsf.util.SessionUtils;

@ManagedBean
@SessionScoped
public class Login implements Serializable {

	private static final long serialVersionUID = 1094801825228386363L;
	
	private String pwd;
	private String msg;
	private String user;

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	//validate login
	public String validateUsernamePassword() {
		boolean valid = LoginDAO.validate(user, pwd);
		if (valid) {
			HttpSession session = SessionUtils.getSession();
			session.setAttribute("username", user);
			return "admin";
		} else {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"Incorrect Username and Passowrd",
							"Please enter correct username and Password"));
			return "login";
		}
	}

	//logout event, invalidate session
	public String logout() {
		HttpSession session = SessionUtils.getSession();
		session.invalidate();
		return "login";
	}
}

getter 및 setter 메서드와 함께 사용자 이름, 암호 및 오류 메시지 필드에 대한 세 개의 문자열 변수 user, pwd 및 msg를 선언합니다. LoginDAO 클래스를 호출하여 데이터베이스에서 사용자 이름과 암호를 가져오고 이를 프런트 엔드 값과 비교하여 사용자 이름과 암호 필드의 유효성을 검사하는 validateUsernamePassword() 메서드를 작성합니다. 통과했다. 사용자 이름과 비밀번호가 일치하지 않으면 "잘못된 사용자 이름과 비밀번호”라는 오류 메시지가 표시됩니다. 또한 logout() 메서드는 첨부된 HTTPSession을 무효화하여 로그아웃을 수행하도록 작성되었습니다. 5단계: 이제 생성합니다. LoginDAO 자바 클래스는 아래와 같습니다. 참고로 데이터베이스 운영 코드는 실제 프로젝트에서 사용하기에 최적화되어 있지 않으며, JSF 애플리케이션에서 인증을 배우는 아이디어이기 때문에 최대한 빨리 작성했습니다.

package com.journaldev.jsf.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.journaldev.jsf.util.DataConnect;

public class LoginDAO {

	public static boolean validate(String user, String password) {
		Connection con = null;
		PreparedStatement ps = null;

		try {
			con = DataConnect.getConnection();
			ps = con.prepareStatement("Select uname, password from Users where uname = ? and password = ?");
			ps.setString(1, user);
			ps.setString(2, password);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				//result found, means valid inputs
				return true;
			}
		} catch (SQLException ex) {
			System.out.println("Login error -->" + ex.getMessage());
			return false;
		} finally {
			DataConnect.close(con);
		}
		return false;
	}
}

validate() 메서드에서 먼저 DataConnect 클래스 getConnection 메서드를 호출하여 데이터베이스에 대한 연결을 설정합니다. PreparedStatement를 사용하여 사용자가 입력한 값으로 데이터베이스에서 데이터를 가져오는 쿼리를 작성합니다. 결과 집합에 데이터가 있으면 입력이 유효하고 true를 반환하고 그렇지 않으면 false를 반환한다는 의미입니다. 6단계: DataConnect.java 클래스를 다음과 같이 생성합니다.

package com.journaldev.jsf.util;

import java.sql.Connection;
import java.sql.DriverManager;

public class DataConnect {

	public static Connection getConnection() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Connection con = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/cardb", "pankaj", "pankaj123");
			return con;
		} catch (Exception ex) {
			System.out.println("Database.getConnection() Error -->"
					+ ex.getMessage());
			return null;
		}
	}

	public static void close(Connection con) {
		try {
			con.close();
		} catch (Exception ex) {
		}
	}
}

Class.forName 메서드를 사용하여 JDBC 드라이버를 로드하고 DriverManager.getConnection 메서드를 사용하여 URL, 사용자 이름 및 암호를 전달하여 데이터베이스에 연결합니다. 7단계: SessionUtils.java를 생성하여 세션 관련 사용자 정보를 얻고 관리합니다.

package com.journaldev.jsf.beans;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class SessionUtils {

	public static HttpSession getSession() {
		return (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
	}

	public static HttpServletRequest getRequest() {
		return (HttpServletRequest) FacesContext.getCurrentInstance()
				.getExternalContext().getRequest();
	}

	public static String getUserName() {
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
		return session.getAttribute("username").toString();
	}

	public static String getUserId() {
		HttpSession session = getSession();
		if (session != null)
			return (String) session.getAttribute("userid");
		else
			return null;
	}
}

여기서 우리는 getUserId 메소드를 통해 로그인한 각 사용자에 대한 세션을 얻음으로써 세션 ID를 특정 사용자 ID에 연결합니다. 8단계: 인증 필터 클래스를 다음과 같이 생성합니다.

package com.journaldev.jsf.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" })
public class AuthorizationFilter implements Filter {

	public AuthorizationFilter() {
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		try {

			HttpServletRequest reqt = (HttpServletRequest) request;
			HttpServletResponse resp = (HttpServletResponse) response;
			HttpSession ses = reqt.getSession(false);

			String reqURI = reqt.getRequestURI();
			if (reqURI.indexOf("/login.xhtml") >= 0
					|| (ses != null && ses.getAttribute("username") != null)
					|| reqURI.indexOf("/public/") >= 0
					|| reqURI.contains("javax.faces.resource"))
				chain.doFilter(request, response);
			else
				resp.sendRedirect(reqt.getContextPath() + "/faces/login.xhtml");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	@Override
	public void destroy() {

	}
}

우리는 destroy 및 doFilter 메서드를 재정의하여 표준 필터 클래스를 구현합니다. doFilter 메소드에서 사용자가 로그인하지 않고 다른 페이지에 액세스하려고 하면 사용자를 로그인 페이지로 리디렉션합니다. 9단계: admin.xhtml을 다음으로 생성합니다.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html">
<h:head>
	<title>Facelet Title</title>
</h:head>
<h:body>
	<h:form>
		<p>Welcome #{login.user}</p>
		<h:commandLink action="#{login.logout}" value="Logout"></h:commandLink>
	</h:form>
</h:body>
</html>

이 페이지는 사용자가 성공적으로 로그인하면 렌더링됩니다. 로그아웃 기능은 Login.java 클래스의 로그아웃 메소드를 호출하여 구현됩니다. 10단계: faces-config.xml 파일을 다음과 같이 생성합니다.

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2" xmlns="https://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee 
	https://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

	<navigation-rule>
		<from-view-id>/login.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>admin</from-outcome>
			<to-view-id>/admin.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>

</faces-config>

JSF 인증 로그인 로그아웃 프로젝트 다운로드