MonacaとNCMBで簡単なアプリを作ってみるハンズオンの資料です。今回のテーマは日報アプリです。この記事では認証周りを実装します。なおコードはNCMBMania/daily_reportにて公開しています。
アプリ全体の処理
まず www/js/app.js
の中で、NCMBを初期化します。これはアプリ全体に関わる処理なので、JavaScriptファイルに記述しています。
const applicationKey = 'YOUR_APPLICATION_KEY'; const clientKey = 'YOUR_CLIENT_KEY'; const ncmb = new NCMB(applicationKey, clientKey);
認証の判定
まず大事なのは認証の判定です。今回は次のように実装しています。これは www/form.html
に実装しています。
ons.getScriptPage().onInit = async function() { const user = ncmb.User.getCurrentUser(); if (!user) { // 未ログインの場合 return $('#formNav')[0].pushPage('login.html'); } try { // セッションの有効性を確認 await ncmb.DataStore('Hello').fetch(); } catch (e) { // セッションが無効な場合エラーになるので、その場合はlocalStorageの認証データを削除 localStorage.removeItem(`NCMB/${ncmb.apikey}/CurrentUser`); ncmb.sessionToken = null; // ログイン画面に遷移 return $('#formNav')[0].pushPage('login.html'); } }
ここで大事なのは、まず ncmb.User.getCurrentUser()
でユーザデータの存在を確認しています。データがなければ未ログイン状態なのでログイン/新規登録画面 login.html
へ遷移します。さらにもしデータがあったとしてもセッションが有効かどうかはリクエストしてみないと分かりません。そこで適当なクラス(今回はHello)へリクエストしています。ここでエラーが出る場合はセッションが無効になっています。
この無効な状態だとログアウト処理も失敗します。そこでlocalStorageに保存されているデータを直接削除し、さらにセッショントークンも削除してログイン/新規登録画面に遷移します。
ログイン/新規登録画面
ログイン/新規登録画面(login.html)ではユーザ名とパスワード、そして担当者名(displayName)を入力しています。今回は処理を簡略化するため、新規登録とログイン処理を一つにまとめています。
認証処理
認証を実行する処理は #login
をクリックした際のイベントで作成していきます。
$('#login').on('click', async e => { // この中に実装します });
まず最初に必要な変数を揃えます。
const userName = $('#userName').val(); const password = $('#password').val(); const displayName = $('#displayName').val();
次にユーザ登録処理を行います。もしすでに登録されている場合はエラーになりますので、try/catchでエラーが出ないようにします。
try { await registerUser(displayName, userName, password); } catch (e) { } // 新規ユーザ登録処理です async function registerUser(displayName, userName, password) { const user = new ncmb.User(); user .set('displayName', displayName) .set('userName', userName) .set('password', password); await user.signUpByAccount(); }
そしてユーザ登録が済んだら、そのユーザ名とパスワードでログイン処理を実行します。こちらはエラーをハンドリングします。エラーになるとしたら、パスワードの不一致になるでしょう。ユーザ名は表示してもいいように、Aclを誰でも表示可としています。ログイン処理が完了したら日報入力画面 form.html
に戻ります。
try { await loginUser(userName, password); $('#formNav')[0].pushPage('form.html'); } catch (e) { ons.notification.alert('ログイン失敗しました。ユーザ名、パスワードを確認してください'); return false; } // ユーザログイン処理です async function loginUser(userName, password) { await ncmb.User.login(userName, password); const user = ncmb.User.getCurrentUser(); const acl = new ncmb.Acl(); acl .setPublicReadAccess(true) .setUserWriteAccess(user, true); await user.set('acl', acl).update(); }
全体の処理は次のようになります。
$('#login').on('click', async e => { const userName = $('#userName').val(); const password = $('#password').val(); const displayName = $('#displayName').val(); // すでに登録済みの場合はエラーになるので、try/catchでエラーを潰します try { await registerUser(displayName, userName, password); } catch (e) { } try { // ログイン処理です。 await loginUser(userName, password); // ログインできたら日報入力画面に遷移します $('#formNav')[0].pushPage('form.html'); } catch (e) { // エラーの場合ID/パスワード不一致になります ons.notification.alert('ログイン失敗しました。ユーザ名、パスワードを確認してください'); return false; } }); // 新規ユーザ登録処理です async function registerUser(displayName, userName, password) { const user = new ncmb.User(); user .set('displayName', displayName) .set('userName', userName) .set('password', password); await user.signUpByAccount(); } // ユーザログイン処理です async function loginUser(userName, password) { await ncmb.User.login(userName, password); const user = ncmb.User.getCurrentUser(); const acl = new ncmb.Acl(); acl .setPublicReadAccess(true) .setUserWriteAccess(user, true); await user.set('acl', acl).update(); }
まとめ
ここまでの処理で、認証されていなかった場合に新規登録/ログイン画面に遷移して、ログインしたら元の画面に戻るまでの処理ができあがりました。次回は日報の入力処理を作成します。