Search code examples
angularlaravelapitokenpassport.js

Laravel Passport Token for Generation


Trying Passport Token System First Time. By URL: http://localhost:8000/oauth/token, Access token and Refresh token can be available. But, unable to use oauth/token Post method in laravel Controller file

Some links: Laravel 5.6 pass oauth/token hanging

Guzzle Cannot make GET request to the localhost (port: 80, 8000, 8080, etc )

namespace App\Http\Controllers\api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\User;
use GuzzleHttp\Client;

class AuthController extends Controller
{


    public function login(Request $request)
    {
        $credentials = request(['email', 'password']);
        $credentialsforToken = request(['email', 'password', 'grant_type', 'client_id', 'client_secret']);
        if(!Auth::attempt($credentials))
            return response()->json([
                'message' => 'Unauthorized'
            ], 401);
        //$user = $request->user();
        //return $user;
        $http = new Client();
        $response = $http->post(url('oauth/token'), [
            'form_params' => [
                'grant_type' => $credentialsforToken['grant_type'],
                'client_id' => $credentialsforToken['client_id'],
                'client_secret' => $credentialsforToken['client_secret'],
                'username' => $credentialsforToken['email'],
                'password' => $credentialsforToken['password'],
                'scope' => '',
            ],
        ]);
        return json_decode((string) $response->getBody(), true);
}}```

Access token and Refresh token must be generated

Solution

  • Do not use Guzzle HTTP to create internal requests, forward the request to Passport route instead, and do not let users post the client secret for security issues, store them in an env backed config for example

    Here's how I would do it

    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Illuminate\Support\Facades\Route;
    use Illuminate\Support\Facades\Validator;
    use Illuminate\Foundation\Auth\AuthenticatesUsers;
    
    class LoginController extends Controller
    {
        /** @var Response $api_response Response returned from oauth */
        public $api_response = null;
        /*
        |--------------------------------------------------------------------------
        | Login Controller
        |--------------------------------------------------------------------------
        |
        | This controller handles authenticating users for the application and
        | redirecting them to your home screen. The controller uses a trait
        | to conveniently provide its functionality to your applications.
        |
        */
    
        use AuthenticatesUsers;
    
        public function __construct(Request $request)
        {
            $request->request->add([
                'username' => $request->email,
                'grant_type' => 'password',
                'client_id' => '2',
                'client_secret' => config('passport.client_secret'),
                'scope' => '',
            ]);
        }
    
        /**
         * Handle a login request to the application.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
         *
         * @throws \Illuminate\Validation\ValidationException
         */
        public function login(Request $request)
        {
            $validation = $this->validateLogin($request);
            if ($validation->fails()) {
                return response(['error' => $validation->errors()], 401);
            }
    
            // If the class is using the ThrottlesLogins trait, we can automatically throttle
            // the login attempts for this application. We'll key this by the username and
            // the IP address of the client making these requests into this application.
            if ($this->hasTooManyLoginAttempts($request)) {
                $this->fireLockoutEvent($request);
    
                return $this->sendLockoutResponse($request);
            }
            if ($this->attemptLogin($request)) {
                return $this->sendLoginResponse($request);
            }
    
            // If the login attempt was unsuccessful we will increment the number of attempts
            // to login and redirect the user back to the login form. Of course, when this
            // user surpasses their maximum number of attempts they will get locked out.
            $this->incrementLoginAttempts($request);
    
            return $this->sendFailedLoginResponse($request);
        }
    
        /**
         * Validate the user login request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return void
         *
         * @throws \Illuminate\Validation\ValidationException
         */
        protected function validateLogin(Request $request)
        {
            return Validator::make($request->all(), [
                $this->username() => 'required|string',
                'password' => 'required|string',
            ]);
        }
    
        /**
         * Attempt to log the user into the application.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return bool
         */
        protected function attemptLogin(Request $request)
        {
            // forward the request to the oauth token request endpoint
            $res = Route::dispatch(request()->create('oauth/token', 'POST', $this->credentials($request)));
            // Set api response for successful login
            $this->api_response = json_decode($res->getContent());
            // Return true or false based on response status code
            return $res->getStatusCode() === 200 ? true : false;
        }
    
        /**
         * Get the needed authorization credentials from the request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        protected function credentials(Request $request)
        {
            return $request->only('email', 'password', 'grant_type', 'client_id', 'client_secret', 'scope');
        }
    
        /**
         * The user has been authenticated.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  mixed  $user
         * @return mixed
         */
        protected function authenticated(Request $request, $user)
        {
            return response()->json(['success' => $this->api_response], 200);
        }
    
        /**
         * Get the failed login response instance.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Symfony\Component\HttpFoundation\Response
         *
         */
        protected function sendFailedLoginResponse(Request $request)
        {
            return response([$this->username() => trans('auth.failed')], 401);
        }
    
        /**
         * Send the response after the user was authenticated.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        protected function sendLoginResponse(Request $request)
        {
            $this->clearLoginAttempts($request);
            return $this->authenticated($request, $this->guard()->user());
        }
    
        /**
         * Log the user out of the application.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function logout(Request $request)
        {
            $request->user()->token()->revoke();
            return $this->loggedOut($request);
        }
    }
    

    This should be a fully functional and secure approach, I hope this helps