Phần còn lại của api php github

Có rất nhiều cách để thiết kế API nhưng phổ biến và được sử dụng nhiều nhất là RESTful API. Vì RESTful API không sử dụng session và cookie nên để xác thực ta sử dụng đến JSON Web Token. Để hiểu rõ hơn về RESTful API và JWT thì trên viblo đã có rất nhiều bài viết về chủ đề này, các bạn có thể tìm hiểu thêm. Trong phạm vi bài viết này mình sẽ sử dụng RESTful API và JWT để xây dựng API đăng nhập Facebook, Twitter và Google. Trước hết ta cần hiểu cơ chế authen của JWT, về cơ bản và dễ hiểu nhất mình xin phép quote đoạn kịch bản authen sau

xác thực. Đây là bản kịch bản phổ biến nhất cho việc sử dụng JWT. Một khi người dùng đã đăng nhập vào hệ thống thì những yêu cầu tiếp theo từ phía người dùng sẽ bao gồm thêm mã JWT, cho phép người dùng có quyền truy cập vào các đường dẫn, dịch vụ và tài nguyên mà cần phải có sự cho phép. . Phương pháp này không bị ảnh hưởng bởi Chia sẻ tài nguyên nguồn gốc chéo [CORS] do nó không sử dụng cookie

Mình xin được mượn tạm hình ảnh về luồng đăng nhập sử dụng jwt trên trang chủ của nó [Link] để giải thích một chút về bản kịch vừa quote ở trên
. Tạm dừng giải thích như sau. Browser chính là Client, khi Client gửi yêu cầu đăng nhập lên server có chứa username/email và password thì server sẽ tạo ra một jwt và trả về cho Client. Kể từ đó khi Client muốn truy cập vào tài nguyên nào cần phải xác thực thì trong yêu cầu đó yêu cầu đính kèm header Authorization chính là cái token đã được trả về từ trước đó. Server nhận yêu cầu kiểm tra xem token hợp lệ thì thực hiện yêu cầu của yêu cầu và trả lại kết quả cho Client. Vâng ở trên chính là luồng xác thực dành cho trường hợp truyền hệ thống sử dụng tên người dùng/email + mật khẩu để đăng nhập. Bây giờ ta cần chỉnh sửa một chút để áp dụng với đăng nhập bên thứ 3. Có thể mường tượng nó như thế này. Đầu tiên ta cần xác thực với bên thứ 3 [Facebook, Twitter, Google] bằng tài khoản của dịch vụ đó và lấy được access_token. Gửi access_token đó lên server, server gửi yêu cầu lấy thông tin người dùng sử dụng access_token của bên thứ 3 đó. Trong thông tin mà API bên thứ 3 trả về sẽ chứa userIdSocial, từ userIdSocial này ta kiểm tra xem đã có trong hệ thống của mình chưa nếu userIdSocial chưa có thì mình sẽ tạo 1 user mới lấy các thông tin từ bên thứ 3 về để điền . sau khi tạo user thì server cũng tạo luôn jwt và trả về cho client, còn nếu userIdSocial đã có trong hệ thống thì mình chỉ cần tạo ra jwt và trả về cho client, flow tiếp theo tương tự như trường hợp bên trên. Như vậy chỉ cần lấy đc access_token thì ta có thể đăng nhập vào hệ thống mà không cần mật khẩu rồi.
Đã hiểu được cơ chế của nó thì mình bắt tay vào code thôi. [đi]

Xây dựng API

Đầu tiên để xây dựng được đăng nhập API bằng mạng xã hội ta cần trải qua một bước gọi tạm thời là "phân tích thiết kế". Việc cần làm là vẽ ra cái Database. Ta có một bảng

composer require facebook/graph-sdk
6 chứa các thông tin về người dùng.
composer require facebook/graph-sdk
7,
composer require facebook/graph-sdk
8,
composer require facebook/graph-sdk
9. Mỗi người dùng có thể liên kết với nhiều mạng xã hội khác nhau vì vậy ta sẽ thiết kế thêm 1 bảng nữa tạm gọi là
// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
0 có quan hệ 1 nhiều với người dùng bảng và có chứa các trường
// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
1,
// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
2,
// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
3. Migration as after

________số 8

Đăng nhập API với Facebook

Đầu tiên ta tải thư viện đồ thị của facebook

composer require facebook/graph-sdk

Ta will code same as flow đã vẽ ra trên. Các bạn cùng xem code nhé, mình comment cho dễ hiểu nhé

// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}

Time job but res only to create route cursor to the function on more is done

composer require facebook/graph-sdk
1

Đăng nhập API với Twitter

Với Twitter, ta sẽ sử dụng thư viện

// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
4 để lấy thông tin người dùng từ Twitter Mã tương tự như với facebook, chỉ có khác là với twitter, ta sẽ nhận tới 2 tham số token là access_token và access_token_secret

composer require facebook/graph-sdk
3

Thêm tuyến đường

composer require facebook/graph-sdk
4

API đăng nhập với Google

Với google thì ta sẽ dùng

// app\Http\Controllers\Api\AuthController.php
// use Facebook\Facebook;
public function facebook[Request $request]
{
    $facebook = $request->only['access_token'];
    if [!$facebook || !isset[$facebook['access_token']]] {
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
    // Khởi tạo instance của Facebook Graph SDK
    $fb = new Facebook[[
        'app_id' => config['services.facebook.app_id'],
        'app_secret' => config['services.facebook.app_secret'],
    ]];

    try {
        $response = $fb->get['/me?fields=id,name,email,link,birthday', $facebook['access_token']]; // Lấy thông tin 
        // user facebook sử dụng access_token được gửi lên từ client
        $profile = $response->getGraphUser[];
        if [!$profile || !isset[$profile['id']]] { // Nếu access_token không lấy đc thông tin hợp lệ thì trả về login false luôn
            return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
        }

        $email = $profile['email'] ?? null;
        $social = SocialNetwork::where['social_id', $profile['id']]->where['type', config['user.social_network.type.facebook']]->first[];
        // Lấy được userId của Facebook ta kiểm tra trong bảng social_networks đã có chưa, nếu có thì tài khoản facebook này 
		// đã từng đăng nhập vào hệ thống ta chỉ cần lấy ra user rồi generate jwt trả về cho client; Ngược lại nếu chưa có thì 
        // ta sẽ tiếp tục dùng email trả về từ facebook kiểm tra xem nếu có user với email như thế rồi thì lấy luôn user đó nếu 
        // không thì tạo user mới với email trên và tạo bản ghi social_network lưu thông tin userId của facebook rồi generate jwt
        // để trả về cho client
        if [$social] {
            $user = $social->user;
        } else {
            $user = $email ? User::firstOrCreate[['email' => $email]] : User::create[];
            $user->socialNetwork[]->create[[
                'social_id' => $profile['id'],
                'type' => config['user.social_network.type.facebook'],
            ]];
            $user->name = $profile['name'];
            $user->save[];
        }

        $token = JWTAuth::fromUser[$user];

        return $this->responseSuccess[compact['token', 'user']];
    } catch [\Exception $e] {
        Log::error['Error when login with facebook: ' . $e->getMessage[]];
        return $this->responseErrors[config['code.user.login_facebook_failed'], trans['messages.user.login_facebook_failed']];
    }
}
5 để verify token và lấy thông tin user. Và khách hàng sẽ gửi id_token khi khách hàng thực hiện đăng nhập bằng Đăng nhập Google

composer require facebook/graph-sdk
6

Thêm tuyến đường

composer require facebook/graph-sdk
7Kết quả

Như vậy mình vừa xây dựng đủ 3 API đăng nhập với 3 dịch vụ ta vẫn thường hay sử dụng mỗi khi phát triển web hoặc ứng dụng. Hi vọng bài viết hữu ích với các bạn. Các bạn có thể tham khảo code tại link Github. https. //github. com/quanvhframgia/api-login-socials Link

Chủ Đề