Laravelでのjwt-auth利用する為のメモ。
Laravelでのjwt-auth利用する為の自分用のメモです。
Laravelの認証機能を利用してテーブルを作成
$ php artisan make:auth
$ php artisan migrate
jwt-authをインストール
composer require tymon/jwt-auth
configファイル生成
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
config/jwt.php
が作成される。
secretの生成
php artisan jwt:secret
.env
ファイルにJWT_SECRET
が追加されているのを確認する。
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
config/auth.php
<?php
return [
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
app/Http/Controllers/Api/AuthController.php
<?php
namespace App\Http\Controllers;
class AuthController extends Controller
{
function login() {
$credentials = request(['email', 'password']);
if (!$token = auth('api')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function logout()
{
auth()->logout();
return response()->json(['message' => 'ログアウトしました。']);
}
public function me()
{
return response()->json(auth()->user());
}
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth("api")->factory()->getTTL()
]);
}
}
トークンの有効期限は60分に設定されている。 変更するにはconfig/jwt.php
を変更する。
routes/api.php
<?php
use Illuminate\Http\Request;
Route::post('/login', 'Api\AuthController@login');
// ユーザー情報と、ログアウトは認証あり
Route::group(['middleware' => 'auth:api'], function () {
Route::get('/me', 'Api\AuthController@me');
Route::post('/logout', 'Api\AuthController@logout');
});
疎通を確認
ユーザーデータを作成
以下を実行。
php artisan make:seeder UsersTableSeeder
以下を設定。
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/####
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
[
'email' => 'admin@example.com',
'password' => bcrypt('password'),
'remember_token' => null,
'created_at' => '2018-10-02 14:28:19',
'updated_at' => '2018-10-02 14:28:19'
]
]);
}
}
実行。
php artisan db:seed
テーブルにユーザー情報が追加されているのを確認する。
ログインしてみる
curl http://localhost:8080/api/login -d email=admin@example.com -d password=password
以下が返却されればOK。
{"access_token":"eyJ0e...","token_type":"bearer","expires_in":3600}
アクセストークンを利用してユーザー情報を取得してみる
curl -H "Authorization: Bearer eyJ0e..." http://localhost:8080/api/me
以下が返却されればOK。
{"id":1,"email":"admin@example.com","email_verified_at":null,"created_at":"2018-10-02 14:28:19","updated_at":"2018-10-02 14:28:19"}
ユーザー登録をしてみる
app/Http/Controllers/Api/AuthController.php
以下を追加。
public function register(Request $request)
{
$user = new User;
$user->fill($request->all());
$user->password = bcrypt($request->password);
$user->save();
return $this->publishToken($request);
}
protected function publishToken($request)
{
$credentials = request(['email', 'password']);
$token = auth('api')->attempt($credentials);
return $this->respondWithToken($token);
}
routes/api.php
に以下を追加
Route::post('/login', 'Api\AuthController@login');
+ Route::post('/register', 'Api\AuthController@register');
実行
curl http://localhost:8080/api/register -d email=sample@example.com -d password=password
以下が返却されればOK。
{"access_token":"eyJ0eXAi...","token_type":"bearer","expires_in":3600}
Eslintのメモ
Eslintの設定は基本的には"extends": "eslint:recommended"
などを利用しているので、あまり個別に設定することはないのですが、 少し変更するときに毎回調べているのでメモしておこうと思います。
有効・無効の設定
値 | 内容 |
---|---|
0 | 無効 |
1 | 有効(警告) |
2 | 有効(エラー) |
オプションの利用
ルールごとに独自のオプションを定義できる場合があります。
//rule: [{"error", "warn", "off"},{option}…]
"semi": ["error", "never"]
設定方法
rulesに設定内容を追加していく。
{
"rules": {
"quotes": [2, "double"],
"curly": 2,
}
}
rules
詳しくは公式を確認。
semi
セミコロン無しを許容しない
// Bad
var website = "eslint.org"
// Good
var website = "eslint.org";
option
◎セミコロンの利用を禁止
semi:["error", "never"]
// Bad
var name = "ESLint";
object.method = function() {
// ...
};
◎セミコロン無しを禁止
semi: ["error", "always"]
var name = "ESLint"
object.method = function() {
// ...
}
indent
インデントの設定
"indent": ["error", "tab"] // or "indent": ["error", 2]
// Bad if (a) { b=c; function foo(d) { e=f; } } //Good if (a) { b=c; function foo(d) { e=f; } }
curly
中括弧の規則を指定する。
// Bad
if (foo) foo++;
// Good
if (foo) {
foo++;
}
accessor-pairs
セッターとゲッターはペアで定義する必要がある
// Bad
var o = {
set a(value) {
this.val = value;
}
};
// Good
var o = {
set a(value) {
this.val = value;
},
get a() {
return this.val;
}
};
dot-notation
ドット表記
// Bad
var x = foo[bar];
// Good
var x = foo.bar;
eqeqeq
型まで判定する
// Bad
if (x == 42) { }
if (obj.getStuff() != undefined) { }
// Good
if (x === 42) { }
if (obj.getStuff() !== undefined) { }
no-alert
alert、confirm、promptを利用しない
// Bad
alert("here!");
confirm("Are you sure?");
prompt("What's your name?", "John Doe");
no-multi-spaces
複数のスペースを許容しない
// Bad
if(foo === "bar") {}
var a = 1;
//Good
if(foo === "bar") {}
var a = 1;
no-process-env
process.envの使用を許容しない。
// Bad
if(process.env.NODE_ENV === "development") { /*error Unexpected use of process.env.*/
//...
}
//Good
var config = require("./config");
if(config.env === "development") {
//...
}
no-redeclare
同じ変数を複数回定義を許可しない。
// Bad
var a = 3;
var a = 10; /*error "a" is already defined*/
//Good
var a = 3;
// ...
a = 10;
no-console
コンソールの消し忘れ
// Bad
console.log("Made it here.");
no-empty
空のブロックを許容しない
// Bad
if (foo) {
}
no-extra-parens
不要な()を許容しない。
// Bad
var a = (b * c);
no-extra-semi
不要なセミコロンを許容しない。
// Bad
var x = 5;;
function foo() {
// code
};
valid-jsdoc
JSDocのコメントルールにあっているか
// Bad
// missing type for @param and missing @returns
/** // 2 errors
* A description
* @param num1 The first number.
*/
function foo(num1) {
// ...
}
LaravelのFilesystemsを利用してファイルをアップロード基礎基礎メモ
LaravelのFilesystemsを利用することで、ファイルストレージを簡単に設定することができます。 今回は「Local Storage」に保存してみたいと思います。
PHP初心者の私には割と時間がかかってしまったので忘れないようにメモしておきます。
S3に保存するのを試したメモはこちらです。
Filesystemの設定
Filesystemの設定はconfig/filesystems.php
にあります。 local、public、s3の設定がされています。
disk | 概要 |
---|---|
local | storage/app/に保存される。 ブラウザからのアクセスは不可。 |
public | storage/app/publicに保存される。 ブラウザからのアクセスは可。 ただしpublic/storageからstorage/app/publicへのシンボリックリンクを貼る必要がある |
s3 | 割愛 |
フロント側
Vue.jsを利用しています。 UIは以下のような感じ。
<template>
<div>
<input type="file" name="file" @change="selectedFile">
<button type="button" @click="upload">登録</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Upload',
data(){
return {
uploadFile:null
}
},
methods: {
selectedFile:(e) => {
let files = e.target.files
if (files.length) this.uploadFile = files[0]
},
upload:() => {
let data = new FormData()
data.append('file', this.uploadFile)
axios.post('/api/upload',data)
}
}
}
</script>
API側
Controllerだけ記載します。
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
class UserController extends Controller
{
public function upload(Request $request,$id)
{
$user = User::find($id);
$thumbnail = $request->file('file');
$filename = time() . '.' . $thumbnail->getClientOriginalExtension();
// strage/app/public配下に保存される
$path =$thumbnail->storeAs('', $filename, ['disk' => 'public']);
$user->thumbnail = $path;
$user->save();
return $path;
}
}
storeAsを利用することで、保存するファイルに任意のファイル名を設定することができます。 第1引数 ・・・ 設定ファイルの指定しているrootディレクトリからのパス 第2引数 ・・・保存する際のファイル名 第3引数 ・・・利用するストレージ(local、public…など)
$thumbnail->storeAs('', $filename, ['disk' => 'public']);
シンボリックリンクを設定
保存するストレージにpublicを設定しても、ブラウザからアクセスすることはできません。 public/storage
から storage/app/public
へのリンボリックリンクを貼る必要があります。
当たり前なのかもしれませんが、シンボリックリンクは、Dockerや、Vagrantを利用している場合は内部で貼る必要があります。
$docker-compose exec --user=laradock workspace bash
$ php artisan storage:link
これで、http://hogehoge/storage/ファイル名
でアップロードしたファイルにアクセスすることができます。
もし、シンボリックリンクをはるときに以下のエラーが出た場合は/public
フォルダの中のstorageを削除してから、もう一度実行してみてください。
ErrorException : symlink(): No such file or directory
手順
cd public rm storage php artisan storage:link
dockerイメージを再構築した際のphp-fpmのエラーメモ
Laradocを利用して、以下のコマンドでdockerイメージを作成した際に、エラーが発生したのメモです。
docker-compose up -d --build nginx mysql workspace
error
E: Failed to fetch http://security-cdn.debian.org/debian-security/pool/updates/main/g/ghostscript/libgs9_9.26a~dfsg-0+deb9u2_amd64.deb 404 Not Found E: Failed to fetch http://security-cdn.debian.org/debian-security/pool/updates/main/g/ghostscript/ghostscript_9.26a~dfsg-0+deb9u2_amd64.deb 404 Not Found E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? ERROR: Service 'php-fpm' failed to build: The command '/bin/sh -c if [ ${INSTALL_IMAGEMAGICK} = true ]; then apt-get install -y libmagickwand-dev imagemagick && pecl install imagick && docker-php-ext-enable imagick ;fi' returned a non-zero code: 100
修正箇所
laradock/php-fpm/DockerfileのImageMagickの箇所を以下に変更。
########################################################################### # ImageMagick: ########################################################################### USER root ARG INSTALL_IMAGEMAGICK=false RUN if [ ${INSTALL_IMAGEMAGICK} = true ]; then \ rm -rf /var/lib/apt/lists/* && \ apt-get update && \ apt-get install -y libmagickwand-dev imagemagick && \ pecl install imagick && \ docker-php-ext-enable imagick \ ;fi