在這個範例中,會員註冊之後會得到一組api token,這組token就等同於會員的通行證,要執行他權限內的行為都要先驗證這組token。
管理者可以查看和刪除任一會員的資料,而非管理者只能看到自己的資料; 編輯的話則只有會員自己能夠編輯自己的資料。驗證身份的程序是在中介層(middleware)中執行。
前置作業:去mysql terminal 建立資料庫
新增專案:
$laravel new 專案名稱
$php artisan make:migration create_tableName_table
public function up() {
Schema::create('members', function (Blueprint $table) {
$table->increments('id');
$table->string('email');
$table->string('password');
$table->boolean('isAdmin')->default(0);
$table->string('api_token');
$table->timestamps();
});
}
$php artisan make:model Model名稱
也可以把上一步建立migration和建立model兩個步驟合併成:
$php artisan make:model Model名稱 -m
其所建立的migration和預設table名稱會是model名稱的小寫開頭、複數型態。
例如:model 名稱 -> Car,migration和table名稱->cars
5. 在app的Member中加入內容,fillable裡放的是能insert進table的欄位,欄位名稱要和table的一致。
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Member extends Authenticatable {
protected $fillable = [
'email', 'password', 'api_token', 'isAdmin',
];
}
$php artisan migrate
就能在MySQL看到建立好的table了。
需要建立的檔案總共有4個,分別是BaseController、MemberController、LoginController和LogoutController。
BaseController為MemberCOntroller的父類別,回傳response資料及訊息內容的method定義在這裡。
BaseController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;
class BaseController
{
public function sendResponse($result, $message)
{
$response = [
'success' => true,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
/**
* return error response.
*
* @return \Illuminate\Http\Response
*/
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if(!empty($errorMessages)){
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
}
MemberController包含會員資料的CRUD,也就是新增 Create、查看Read、編輯Update、刪除Delete。
動作 | HTTP Method | function name |
---|---|---|
查看會員 | get | index |
註冊會員 | post | store |
編輯會員 | put | update |
刪除會員 | delete | destroy |
MemberController.php
<?php
namespace App\Http\Controllers;
use App\Member;
use Illuminate\Support\Facades\Auth;
use Str;
use Illuminate\Http\Request;
use App\Http\Controllers\BaseController as BaseController;
use Validator;
class MemberController extends BaseController
{
/**
* Display a listing of the resource.
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index()
{
$admins = Member::all();
$members = [
'mail' => Auth::user()->email,
'password' => Auth::user()->password,
];
if (Auth::user()->isAdmin) //是管理者,回傳所有會員資料
return $this->sendResponse($admins->toArray(), 'Members retrieved successfully.');
else //不是管理者,回傳該會員自己的資料
return $members;
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function adminStore(Request $request) { //管理者註冊的function
try {
$request->validate([ //這邊會驗證註冊的資料是否符合格式
'email' => ['required', 'string', 'email', 'max:255', 'unique:members'],
'password' => ['required', 'string', 'min:6', 'max:12'],
]);
$apiToken = Str::random(10);
$create = Member::create([
'email' => $request['email'],
'password' => $request['password'],
'isAdmin' => '1',
'api_token' => $apiToken,
]);
if ($create) {
return "Register as an admin. Your Token is $apiToken.";
}
} catch (Exception $e) {
sendError($e, 'Registered failed.', 500);
}
}
public function store(Request $request)
{
$request->validate([
'email' => ['required', 'string', 'email', 'max:255', 'unique:members'],
'password' => ['required', 'string', 'min:6', 'max:12'],
]);
$apiToken = Str::random(10);
$create = Member::create([
'email' => $request['email'],
'password' => $request['password'],
'api_token' => $apiToken,
]);
if ($create)
return "Register as a normal user. Your api token is $apiToken";
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Member $members
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
$input = $request->all();
$validator = Validator::make($input, [ //修改會員資料一樣要驗證是否符合格式
'email' => ['string', 'email', 'max:255', 'unique:members'],
'password' => ['string', 'min:6', 'max:12'],
]);
if ($validator->fails()) {
return $this->sendError('Validation Error.', $validator->errors());
}
$member = Auth::user();
if ($member->update($request->all()))
return $this->sendResponse($member->toArray(), 'Member updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param \App\Member $members
* @return \Illuminate\Http\Response
*/
public function destroy(Member $members)
{
if ( Auth::user()->isAdmin){ //驗證是否為管理者
if ($members->delete())
return $this->sendResponse($members->toArray(), 'Member deleted successfully.');
}
else
return "You have no authority to delete";
}
}
會員每次都入都會產生一組新的token,登入成功後,這組token會被存進資料庫,之後的查看、編輯等動作都會驗證這組token來判斷他的身份。
LoginController.php
<?php
<?php
namespace App\Http\Controllers;
use Str;
use App\Member;
use Illuminate\Http\Request;
class LoginController
{
public function login(Request $request)
{
$member = Member::where('email', $request->email)->where('password', $request->password)->first();
$apiToken = Str::random(10); //隨機產生一組10個英數字組成的字串
if($member){
if ($member->update(['api_token'=>$apiToken])) { //更新 api_token
if ($member->isAdmin)
return "login as admin, your api token is $apiToken";
else
return "login as user, your api token is $apiToken";
}
}else return "Wrong email or password!";
}
}
會員登出後,會將剛才登入時產生的token從資料庫中清除,該欄會被'logged out'字串取代。
LogoutController.php
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Str;
use App\Member;
class LogoutController extends Controller
{
public function logout()
{
if ( Auth::user()->update(['api_token'=>'logged out'])) { //更新api token
return "You've logged out";
}
}
}
php artisan migrate
php artisan make:migration add_paid_to_table_name --table="table_name"
$table->dropColumn('欄位名稱');
php artisan migrate:rollback
php artisan migrate:fresh
php artisan migrate:refresh
php artisan migrate:refresh --step = 3
php artisan migrate:reset
安裝套件:
composer require doctrine/dbal
新增更改欄位的schema:
php artisan make:migration change_column_table
up function中定義要更改的欄位
public function up()
{
//Schema這邊table method的update是修改欄位,create則是新增欄位
Schema::table('posts', function (Blueprint $table) {
$table->dateTime('created_at')->change();
$table->dateTime('updated_at')->change();
});
}
更改欄位:
php artisan migrate