【monaca】JavaScriptでアプリの簡易パスロック機能を作る
monacaで作ったアプリにパスロックを実装したいな、と思ったのですが、バックエンドの知見がないのでJavaScriptだけでパスロックもどきを実装してみました。
仕組みとしては、パスコード入力画面をモーダルとしてホーム画面に被せ、入力したパスコードがあらかじめローカルストレージに保存しておいたパスコードと一致したらモーダルを消す、という単純な機能です。
外からソースコードをいじれないハイブリッドアプリだからこそ使える、なんちゃって認証です。
完成形
パスロック設定メニュー
まず完成形がこちら。
こちらパスロック設定メニュー。
※PCだと表示が崩れて見えますがスマホで使うための画面なので悪しからず。
パスコード入力画面
パスロック設定メニューを作る
新規パスコードを入力するフォーム
<div class="pass-container"id="newpass">
<div>パスワードを設定/更新</div>
<label>
<input type="password" maxlength="4" pattern="[1-9][0-9]*" inputmode="numeric" id="newpassword" required>
</label>※数字4字
</div>
<div class="pass-container"id="confirmation">
<div>確認のためもう一度入力してください。</div>
<label>
<input type="password" maxlength="4" pattern="[1-9][0-9]*" inputmode="numeric"id="pass-confirm" onchange="Varidate()" required>
</label>
<div class="green"id="log"></div>
</div>
<div class="modalbefore btn"id="pass-set">決定</div>
input type="password"だと英数字キーボードが出るのでinputmode="numeric"でテンキーが出るようにします。
function Varidate(){
var NewPass=document.getElementById("newpassword").value;
var ConfirmPass=document.getElementById("pass-confirm").value;
var Log= document.getElementById("log");
if(NewPass===ConfirmPass){
Log.innerHTML="一致";
document.getElementById("pass-set").classList.remove("modalbefore");
Log.classList.remove("red");
Log.classList.add("green");
}
else{
Log.innerHTML="不一致";
Log.classList.remove("green");
Log.classList.add("red");
}
};
document.getElementById("pass-set").addEventListener("click",()=>{
var savedpass=document.getElementById("newpassword").value;
var Log= document.getElementById("log");
if(savedpass.length<4){
Log.innerHTML="パスワードは4字で設定してください";
Log.classList.remove("green");
Log.classList.add("red");
}else{
localStorage.setItem("kin-pass",savedpass);
alert("パスワードを"+savedpass+"に設定しました");
}
});
パスコードがnullの状態で保存すると解除できなくなって詰むので、初期の状態ではパスコードを保存する「決定」ボタンは消しておきます。
確認用フォームに入力し終わったタイミングで両方のフォームを参照し、互いのvalueが一致すれば「決定」ボタンを出して保存できるようにします。
決定ボタンを押すとフォームのvalueが取得されます。パスコードが4文字未満だと保存せず、input要素にmaxlength="4"をつけているので、保存できるパスコードは4文字になります。保存できたらアラートを出してパスワードをユーザーに確認させます。
<div class="passlock-box" id="passlock-onoff">
<i class="fas fa-lock-open" id="lock-open"></i>
<i class="fas fa-lock none" id="lock"></i>
<div class="switch">
<div class="switchbtn" id="Switchbtn">
<div class="btncircle" id="iosbtn" ></div>
<div class="btncircle none" id="on"></div>
</div>
</div>
</div>
// <!-- ONにした時 -->
document.getElementById("iosbtn").addEventListener("click",()=>{
var PASS=localStorage.getItem("kin-pass");
if(PASS==null){
alert("パスワードが設定されていないためロックをONにできません");
}else{
document.getElementById("iosbtn").classList.add("none");
document.getElementById("on").classList.remove("none");
document.getElementById("lock-open").classList.add("none");
document.getElementById("lock").classList.remove("none");
document.getElementById("Switchbtn").classList.add("swi-btn-active");
localStorage.setItem("passlock",1);
}
});
// <!-- OFFにした時 -->
document.getElementById("on").addEventListener("click",()=>{
document.getElementById("iosbtn").classList.remove("none");
document.getElementById("on").classList.add("none");
document.getElementById("lock").classList.add("none");
document.getElementById("lock-open").classList.remove("none");
document.getElementById("Switchbtn").classList.remove("swi-btn-active");
localStorage.setItem("passlock",0);
});
パスロックをONにした時はlocalStorage.setItem("passlock",1);
、OFFにした時はlocalStorage.setItem("passlock",0);
初期状態ではもちろんパスロックはOFFになっていますが、パスロックをONにしたら、次にアプリを開いた時にはパスロックがONになっていないといけません。つまりパスロックがONなのかOFFなのかということをブラウザに記憶させ、次回読み込み時にはそれに基づいてパスロック入力モーダルを表示するかしないか分岐する必要があります。そこで、パスロックがONの状態を1、OFFの状態を0として、ON/OFFを切り替えた時に0か1かを保存しています。
パスコード入力画面を作る
<!-- パスコード入力モーダル -->
<div class="off"id="enterpass-body">
<div class="delay" id="enterpass-container">
<div id="enterpass-text"> パスワード</div>
<label>
<input type="password" maxlength="4" pattern="[1-9][0-9]*" inputmode="numeric" required class="shake-2" id="enterpass" onchange="unlock()">
</label>
</div>
</div>
//パスコードが一致したら解除
function unlock(){
var PassWord=localStorage.getItem("kin-pass");
var Enterpass=document.getElementById("enterpass").value;
if(PassWord===Enterpass){
document.getElementById("enterpass-body").classList.add("off");
}else{
document.getElementById("enterpass").classList.toggle("shake");
document.getElementById("enterpass").classList.toggle("shake-2");
}
}
// ページの読み込み時
window.addEventListener("load",()=>{
var OnOff=localStorage.getItem("passlock")
if(OnOff==1){
document.getElementById("enterpass-body").classList.remove("off");
}else{
console.log("パスロックOFF");
};
});
パスコード入力モーダルはビューポートいっぱいに画面に重ねられており、デフォルトではdisplay:none;
です。アプリを開いたときに、ローカルストレージから0か1かを取得し、1なら(パスロックがONなら)パスコード入力モーダルを表示させます。
パスワードを入力したとき、先程のパスロックメニューで設定したパスコードと、入力されたパスコードが同じであれば、パスロック解除となります。
以上が、JavaScriptでフロントだけで簡易パスロックを実装する方法です。
今回パスロックを実装したアプリ:禁欲エボリューション
Discussion