SEワンタンの独学備忘録

IT関連の独学した内容や資格試験に対する取り組みの備忘録

自作ブラウザ拡張機能でシームレスな自動ログインを実装する


以前、ブラウザの拡張機能の自作に関する記事を作成しましたが、今回は簡単に実現できる自動ログインを実装してみます。
各種webサービスの自動ログインを実現する仕組みはかなり様々な方法がありますが、この方法による特徴としては以下の点が挙げらます。

・通常のブラウザ操作に組み込まれるためシームレスな自動ログインが実装できる。
・特にツールなどがなくても実装でき、簡単。
・自動ログインしたくない場合には、(いちいち)拡張機能の解除が必要になる(または実装に工夫が必要)

各webページごとに実装する(webページの作りを把握する必要がある)というのは簡単に実現できる方法でやる場合にはどのような方法でも概ね同じでしょう。

ここでいうシームレスな自動ログインというのは、普段と同じブックマークから開いて自動ログインされるという感じのことです。
ただ、完全に組み込まれてしまうため勝手にログインされてしまうので、ログインしたくない場合には拡張機能の解除が必要になります。これはしっかりと作りこめば拡張機能としてのON・OFF機能をつけたりで回避できると思いますが、少し大変そうなので今回は扱いません。

また、他の人が使う可能性があるPCの場合には、自動でログインがされる上、ユーザ情報やパスワードも簡単に確認できてしまうことになるのでセキュリティ的に問題がある場合には自己責任でよく考えてください。

ブラウザはChromeを対象としていますが、Edgeやfirefoxでも同様のことができると思います。

ブラウザ拡張機能の自作について

そもそものブラウザの拡張機能の基本については以下の記事があります。
拡張機能の設定方法や基本的なファイルについてはそちらを参照ください。

www.wantanblog.com

但し、基本というには内容的に全然足りていないので、本格的に学びたい場合には別の記事などを参照推奨します。

ニコニコ動画の自動ログインを実装する

今回は「ニコニコ動画」を題材に挙げていますが、基本的にはサイトはなんでもいいです。
最初は1サイトを対象とします。

manifest.json

まずは「manifest.json」を実装します。

今回は以下のような内容になります。

・manifest.json

{
	"manifest_version": 2,
	"name": "nikoniko",
	"version": "1.0",
	"description": "ニコニコ動画のログイン",
	"content_scripts": [{
		"matches": ["https://account.nicovideo.jp/login"],
		"js": [
			"main.js"
		]
	}]
}

重要なのは「content_scripts」の部分です。

見ればなんとなく分かりますが、
matches」には対象サイトのURLを「js」には実装を行うjsファイル名を記述します。

仕組みとしては、webページを開いた際に指定したURLにマッチした場合にmain.jsを動作させるという感じになります。

その他の部分は表示などになるので、自分で作成して自分のみが使用する場合にはご自由に。

main.js

jsファイルについては「manifest.json」で指定したものであればファイル名は任意になります。
実装方法についてはいろいろあると思いますが、今回は以下のように実装してみました。実装方法についてはログインさえできれば同じ実装でなくても問題ありません。

・main.js

//ニコニコ動画のログイン処理

document.getElementById('input__mailtel').value = "メールアドレスまたは電話番号";
document.getElementById('input__password').value = "パスワード";

document.getElementById('login_form').submit();

メールアドレスやパスワードの要素名については、対象のwebページで開発者モード(F12)で調べます。
「メールアドレスまたは電話番号」、「パスワード」になっている部分はもちろん今は隠しているだけなので実際のメールアドレスやパスワードを入力します。

後はテキストボックスにjsで値を格納して、formを送信しているだけです。

動作確認

作成したファイルを任意の場所に格納します。
例えばC:\browser_option\nikoniko_login など

Chromeの拡張機能ページの拡張機能の読み込みでファイルを格納したフォルダを指定します。
エラーなく読み込めたら対象の拡張機能を有効化します。

f:id:wantanBlog:20210329232500p:plain

設定したら、対象のログインページを開き直してログイン情報が入力され、自動ログインがなされたら実装はうまくいっています。

複数サイトに対応させる

上記の方法は「manifest.json」の特性を利用した実装とも言えますが、複数サイトの自動ログインを実装したい場合にはサイトの数だけ拡張機能が増えるのであまり効率がよいとは言えません

なので次に一つの拡張機能で複数サイトに対応させる実装を考えます。
まぁjsに頼った感じになるのであまり面白味はないです。

後は、ログイン情報をソースに直書きからは脱却できていないのでサイト数を増やすほど、ユーザ情報やパスワードが増えるので取り扱いの注意度は増します。
jsで暗号・複合を実装してもいいかもしれませんが、それでも扉の前に鍵が置いてあるような感じになると思うので気持ち程度の対策になるでしょうか。

manifest.json

・manifest.json

{
	"manifest_version": 2,
	"name": "auto_login",
	"version": "1.0",
	"description": "各種サイトの自動ログイン",
	"content_scripts": [{
		"matches": ["http://*/*","https://*/*"],
		"js": ["main.js"]
	}]
}

今回のmanifest.jsonは、matchesではhttpあるいはhttpsで接続する全てのサイトに対してmain.jsが動作するようにします。

ほぼjsに丸投げしているだけになるので、正直キレイな実装方法とは言えないかもしれません。

main.js

・main.js

var nikoniko_url = 'https://account.nicovideo.jp/login'
var gihub_url = 'https://github.com/login'
var biz_url = 'https://www.bizreach.jp/login/'
var hatenablog_url = 'https://www.hatena.ne.jp/login'

var now_url = location.href
var ref_url = document.referrer

if(now_url.startsWith(nikoniko_url) && !(ref_url.startsWith(nikoniko_url))){
	// ニコニコ動画ログイン
	document.getElementById('input__mailtel').value = "userid";
	document.getElementById('input__password').value = "password";

	document.getElementById('login_form').submit();
	
}else if(now_url.startsWith(gihub_url)){
	// githubのログイン
	document.getElementById('login_field').value = "userid";
	document.getElementById('password').value = "password";

	document.forms[0].submit();

}else if(now_url.startsWith(biz_url)){
	// ビズリーチのログイン
	document.getElementById('email').value = "userid";
	document.getElementById('password').value = "password";
	
	document.getElementById('executor').submit();

}else if(now_url.startsWith(hatenablog_url)){
	// はてなブログのログイン
	document.getElementById('login-name').value = "userid;
	document.getElementsByName('password')[0].value = "password";

	document.forms[0].submit();

}

もう拡張機能というよりはjsに頼った形になってしまったので軽くやっていることを確認します。

main.jsはwebページを開いたときに一度走るので、あらかじめ埋め込んだ対象サイトのURLと突合させ、対象のサイトだった場合にログイン処理を実行します。
基本的にstartsWithで対応しているのはログイン画面の表示方法によって後ろにパラメータがつくサイトも多いためです。
ニコニコ動画のログイン判定にのみつけている&& !(ref_url.startsWith(nikoniko_url))は自動ログインに失敗したときに無限ループしてしまうのを避けるためです。ここは使い始めたら、ほとんど不要な考慮かもしれません。
あとはテキストボックスがidだったりnameだったりするのは実際にサイトのつくりを見てそれぞれ対応した結果です。
submitにidもnameも振られていない場合もあったので、やや無理やりですが、0番目(1番目)のformssubmitする形で対応しました。

もっとかっこいい実装方法はいくらでもあると思いますが、ささっと実装したかったのでこんなところで。

ここまで作成したら、後は前述と同様に拡張機能として取り込みを行い有効化する。対象のサイトを開いて自動ログイン処理が行われることを確認できたらOK。