9 ログインおよびログアウト機能の作成

HR Webアプリケーションには、hradminhrstaffの2人のユーザーがいます。

HRアプリケーションにログインすると、Webアプリケーションの詳細が記載されたランディング・ページが表示されます。hradminおよびhrstaffには、異なる権限と異なる機能へのアクセス権があります。

ユーザー名とパスワードを入力するログイン・ページ。

この章では、アプリケーションでログインおよびログアウト機能を構築するために必要なクラスと追加コードを示します。

  • ログイン機能用のXMLファイルtomcat-users.xmlを作成します。

  • ユーザーをログインするHTMLページlogin.htmlを作成します。

  • エラー・メッセージを表示するHTMLページlogin-failed.htmlを作成します。

  • ログイン中にユーザーを認証するweb.xmlの作成

  • アプリケーションの詳細を表示するHTMLページabout.htmlを作成します。

  • ランディング・ページindex.htmlを作成し、リダイレクト用のhtmlページを定義します。

  • ログアウトを処理するコードをサーブレットWebController.javaに追加します。

tomcat-users.xmlの作成

XMLファイルtomcat-users.xmlを作成し、アクセスを許可するユーザーをリストします。各ユーザーにユーザー名とパスワードの両方を指定します。

クラス名: /java/HRWebApp/tomcat-users.java

Githubの場所: tomcat-users.xml

xmlファイルを作成するステップ:

  1. ファイルtomcat-users.xmlを作成します。
    <?xml version='1.0' encoding='utf-8'?> z
    <tomcat-users xmlns="http://tomcat.apache.org/xml"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0">
    <role rolename="manager"/>
    <role rolename="staff"/>
    <user username="hradmin" password="welcome" roles="manager,staff"/>
    <user username="hrstaff" password="welcome" roles="staff"/>
    </tomcat-users>
  2. このファイルをマシンのTOMCAT_HOME/conf/tomcat-users.xmlの下に配置します。

login.htmlの作成

ログイン・ページは、Webアプリケーションのメイン・ページを起動すると表示されます。ログイン・ページには、ユーザー名およびパスワードを取得するためのフィールドが表示されます。

クラス名: src/main/webapp/login.html

Githubの場所: login.html

HTMLページを作成するステップ:

  1. login.htmlのタイトル、ヘッダーおよびスタイルシートを作成します。
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Login to Jdbc Web Sample application</title>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <style>
    #cent {
        position:absolute;
        top:50%;
        left:50%;
        margin-top:-50px; /* this is half the height of your div*/
        margin-left:-100px; /*this is half of width of your div*/
      }
       td {
         height: 30px;
       }
    
    </style>
    </head>
  2. ユーザーが入力したログイン資格証明を発行する<body>および<form>を作成します。
    <body>
    <div id="cent">
    <form method="POST" action="j_security_check">
    <table>
    <tr>
    <td colspan="2">Login to the Jdbc Web Sample application:</td>
    </tr>
    <td>Name:</td>
    <td><input type="text" name="j_username" /></td>
    </tr>
    <tr>
    <td>Password:</td>
    <td><input type="password" name="j_password"/></td>
    </tr>
    <tr>
    <td colspan="2"><input type="submit" value="Go" /></td>
    </tr>
    </table>
    </form>
    </div>
    </body>

login-failed.htmlの作成

ログインに失敗した場合にエラー・メッセージを表示するHTMLページ。

クラス名: src/main/webapp/login-failed.html

Githubの場所: login-failed.html

HTMLページを作成するステップ:

  1. 次に示すようにlogin-failed.htmlを作成します。
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Login Failed</title>
    </head>
    <body>
    <p>
    Sorry, login failed!
    </p>
    </body>
    </html>

web.xmlの作成

web.xmlファイルは、ログイン・ページがユーザーに表示されたときにユーザーを認証するための記述子で構成されています。

クラス名: src/main/webapp/WEB-INF/web.xml

Githubの場所: web.xml

xmlファイルを作成するステップ:

  1. 次のコードを使用して、web.xmlファイルを作成します。
    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
    <display-name>Jdbc Web Sample</display-name>
    <security-role>
    <role-name>manager</role-name>
    </security-role>
    <security-role>
    <role-name>staff</role-name>
    </security-role>
    <security-constraint>
    <web-resource-collection>
    <web-resource-name>Wildcard means whole app requires 
    authentication</web-resource-name>
    <url-pattern>/*</url-pattern>
    <http-method>GET</http-method>
    <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>manager</role-name>
    </auth-constraint>
    <user-data-constraint>
    <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
    </security-constraint>
    <security-constraint>
    <web-resource-collection>
    <web-resource-name>Wildcard means whole app requires 
    authentication</web-resource-name>
    <url-pattern>/*</url-pattern>
    <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>staff</role-name>
    </auth-constraint>
    <user-data-constraint>
    <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
      </security-constraint>
    <login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
    <form-login-page>/login.html</form-login-page>
    <form-error-page>/login-failed.html</form-error-page>
    </form-login-config>
    </login-config>
    </web-app>

about.htmlの作成

about.htmlファイルには、HRアプリケーション、ユーザーおよび機能に関する情報が表示されます。

クラス名: src/main/webapp/about.html

Githubの場所: about.html

HTMLページを使用するステップ: about.HTMLをダウンロードして、それをアプリケーションで使用します。

index.htmlの作成

index.htmlファイルは、HR Webアプリケーションに関するすべての詳細で構成されています。ユーザーおよび機能の詳細を説明します。

クラス名: src/main/webapp/index.html

Githubの場所: index.html

HTMLページを作成するステップ:

  1. index.htmlのタイトル、ヘッダーおよびスタイルシートを作成します。
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Employee table listing</title>
    <link rel="stylesheet" type="text/css" href="css/app.css" >
    <style>
    iframe:focus {
    outline: none;
    }
    iframe[seamless] {
    display: block;
    }
    </style>
    </head>
    <body>
  2. ナビゲーション・リンクとログアウトを使用して、機能のアクションと<body>を作成します。
    <body>
    <div id="sideNav" class="sidenav">
    
    <a href="javascript:void(0)" class="closebtn" onclick="closeNav()" class="staff">×</a>
    <a href="javascript:switchSrc('listAll.html')" class="staff">List All</a>
    <a href="javascript:switchSrc('listById.html')" class="staff">Search By Id</a>
    
    <a href="javascript:switchSrc('listByName.html')" class="manager">Update Employee Record</a>
    <a href="javascript:switchSrc('incrementSalary.html')" class="manager">Increment Salary</a>
    <a href="javascript:switchSrc('about.html')">About</a>
    </div>
    <div id="main">
    <div align="right">
    <div
    id="myrole"
            style="display:inline; color:#393318; display: block; background-color:#eff0f1;position: absolute; top: 20px; right: 8%;"
        >myrole</div>
    <a href="javascript:void(0)"
           onclick="logout()"
           class="staff"
           style="display: block; position: absolute; top: 20px; right: 1%">Logout</a>
    </div>
    <div>
    <span style="font-size:30px;cursor:pointer" onclick="openNav()"> Java Get Started HR Web Application		</span>
    </div>
    <div>
    <iframe id="content"
    src="about.html"
    frameborder="0"
    style="overflow:hidden; height:100%; width:100%"
    height="100%"
    width="100%"></iframe>
    </div>
    </div>
    <script>
    function openNav() {
      document.getElementById("sideNav").style.width = "256px";
      document.getElementById("main").style.marginLeft = "256px";
    }
    
    function closeNav() {
      document.getElementById("sideNav").style.width = "0";
      document.getElementById("main").style.marginLeft= "0";
    }
    
    function switchSrc(src) {
      document.getElementById('content').src = src;
    }
    
    function logout() {
    
      var xmllogout = new XMLHttpRequest();
      xmllogout.open("GET", "WebController?logout=true", true, "_", "_");
      xmllogout.withCredentials = true;
      // Invlalid credentials to fake logout
      xmllogout.setRequestHeader("Authorization", "Basic 00001");
      xmllogout.send();
    
      xmllogout.onreadystatechange = function() {
        window.location.replace("index.html");
      }
    
     return true;
    }
    
    var xmlhttp = new XMLHttpRequest();
    var url = "getrole";
    
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        role = xmlhttp.responseText;
        console.log("role: " +role);
        if (role == "staff") {
          console.log ("disabling manager");
          var x = document.getElementsByClassName('manager');
          for(i = 0; i < x.length; ++i) {
            x[i].style.display = 'none';
          }
        }
        document.getElementById('myrole').innerHTML = ' '+role+' ';
      }
    }
    xmlhttp.open("GET", url, true);
    xmlhttp.send();
    </script>
    </body>

リクエストを処理するコードのサーブレットへの追加

アプリケーションにログインおよびログアウトするための関連コードをWebController.javaに追加します。

クラス名: src/main/java/com/oracle/jdbc/samples/web/WebController.java

Githubの場所: WebController.java

コードを追加するステップ:

  1. WebController.javaクラスを開きます。WebController.javaを作成するには、リクエストを処理するサーブレットの作成を参照してください。同じクラスを使用して、必要なコードを追加します。
  2. ユーザーのステータスを取得する変数LOGOUTを宣言します。これはグローバル変数であるため、processRequest()メソッドの外部で、ただしWebControllerクラスの内部で宣言します。
    private static final String LOGOUT = "logout";
  3. メソッドprocessRequest()は、ListAll機能ですでに作成されています。次に、ログアウト機能を実装するコードを追加します。 入力に基づいて呼び出す機能を検証するifブロックを作成します。入力値がLOGOUTかどうかを確認します。
    if ((value = request.getParameter(LOGOUT)) != null) {
    /* Getting session and then invalidating it */
    
        HttpSession session = request.getSession(false);
       if (request.isRequestedSessionIdValid() && session != null)   {
            session.invalidate();
       }
    handleLogOutResponse(request,response);
       response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    return;
    } 
    
  4. 入力値がLOGOUTの場合は、ユーザーのログアウトを処理するメソッドを呼び出します。
    
    private void handleLogOutResponse(HttpServletRequest request,
    HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
          cookie.setMaxAge(0);
          cookie.setValue(null);
          cookie.setPath("/");
          response.addCookie(cookie);
        }
      }