Search code examples
laravelapiauthenticationlumenlaravel-passport

Laravel client authentification with external Laravel passport lumen api


I have been looking online but i can't find any way of doing it. Let me explain, i have an API (Laravel passport on lumen), i tested it with Postman, i get my access token with oauth, everything is fine. Now i have another Laravel application and i want to know how i can keep all my authentification stuff using the API to login. I have seen lot of apps that actualy retrieve an api_token and they use 'Auth::user()->where('api_token', $token)'. But i find this wrong because i don't want my client to have access to the database, i want every request to the database to be handled by the API. Is that possible?


Solution

  • Let say you want to login to a laravel backend app via api. make sure you install guzzle.

    Route(api): Route::POST('/login', 'AuthController@login')

    Controller: AuthController.php

    public function login(Request $request)
    {
        $this->validate($request, [
            'email' => 'required|email',
            'password' => 'required|string',
        ]);
    
       $http = new \GuzzleHttp\Client;
    
       try {
        $response = $http->post(config('services.passport.login_endpoint'), [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => 'your client_id',
                'client_secret' => 'your client_secret',
                'username' => $request->email,
                'password' => $request->password,
                // 'scope' => '',
            ],
        ]);
    
        return $response->getBody();
    
        } catch (\GuzzleHttp\Exception\BadResponseException $e) {
            if ($e->getCode() == 401) {
                return response()->json(['message' => 'This action can\'t be perfomed at this time. Please try later.'], $e->getCode());
            } else if ($e->getCode() == 400) {
                return response()->json(['message' => 'These credentials do not match our records.'], $e->getCode());
            }
    
            return response()->json('Something went wrong on the server. Please try letar.', $e->getCode());
        }
    }
    

    In your front-end app for example vuejs, even laravel using vue component. As you can see, i'm using boostrap-vue but feel free to use the regular html elements

    <template>
      <div>
        <form @submit.prevent="login()">
            <b-form-group label="Email">
              <b-input placeholder="E-Mail" class="ml-1" v-model="form.email" type="email" name="email" :class="{ 'is-invalid': form.errors.has('email') }"/>
              <has-error :form="form" field="email"></has-error>
            </b-form-group>
    
            <b-form-group>
              <div slot="label" class="d-flex justify-content-between align-items-end">
                <div>Password</div>
                <a href="javascript:void(0)" class="d-block small">Forgot password?</a>
              </div>
              <b-input v-model="form.password" type="password" name="password" :class="{ 'is-invalid': form.errors.has('password') }" />
                <has-error :form="form" field="password"></has-error>
            </b-form-group>
    
            <div class="d-flex justify-content-between align-items-center m-0">
              <b-check v-model="form.rememberMe" class="m-0">Remember me</b-check>
              <b-btn type="submit" variant="primary">Sign In</b-btn>
            </div>
          </form>
       </div>
      <template>
    
    <script>
    
    
    export default ({
      name: 'pages-authentication-login-v2',
      metaInfo: {
        title: 'Login'
      },
    
      state: {
          token: localStorage.getItem('access_token'),
      },
    
      mutations: {
        login(state, token) {
          state.token = token
        },
      },
    
      data: () => ({
          form: new Form({
              email: '',
              password: '',
          })
      }),
    
      methods: {
    
      login(){
            this.form.post('/api/login')
            .then((response) =>{
                const token = response.data.access_token
                localStorage.setItem('access_token', token)  
                // console.log(response);
                this.$router.push('/dashboard');
            })
    
            .catch((error)=>{
                this.$toasted.error('Ooops! Something went wrong', {
                    icon : "warning",
                    theme: "bubble",
                    closeOnSwipe: true,
                    position: "top-right",
                    duration : 5000,
                    singleton: true,
                })
            });
      },
    
      }
    })
    </script>