使用外部 Laravel 护照流明 api 进行 Laravel 客户端身份验证

Posted

技术标签:

【中文标题】使用外部 Laravel 护照流明 api 进行 Laravel 客户端身份验证【英文标题】:Laravel client authentification with external Laravel passport lumen api 【发布时间】:2020-03-25 09:38:51 【问题描述】:

我一直在网上寻找,但我找不到任何方法。让我解释一下,我有一个 API(流明上的 Laravel 护照),我用 Postman 对其进行了测试,我用 oauth 获得了我的访问令牌,一切都很好。现在我有另一个 Laravel 应用程序,我想知道如何使用 API 登录来保留我的所有身份验证内容。我见过很多实际上检索 api_token 的应用程序,它们使用 'Auth::user()->where('api_token', $token)'。但我发现这是错误的,因为我不希望我的客户能够访问数据库,我希望对数据库的每个请求都由 API 处理。这可能吗?

【问题讨论】:

您是否使用 Laravel 密码进行身份验证 API? Laravel 护照是的,我想要 然后你必须在 api.php 路由中定义你的所有路由,并从你的前端应用程序中使用 axios 之类的东西发出 http 请求。 是的,我知道如何向我的护照 API 发出请求并收集资料。我想在我的前端应用程序中使用登录身份验证。我如何从外部登录 api 处理 laravel 使用会话 你的问题对我来说不是很清楚..我猜你正在构建一个 SPA ..你有两个应用程序一个在流明上运行,另一个在 Laravel 上运行你想要它们交换数据 .. 我建议您仅将 Laravel 用作 API 而忘记流明,因为拥有一个目标不同的应用程序并不值得 【参考方案1】:

假设您想通过 api 登录到 laravel 后端应用程序。确保安装 guzzle。

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

控制器: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());
    

在您的前端应用程序中,例如 vuejs,甚至 laravel 使用 vue 组件。如您所见,我使用的是 boostrap-vue,但可以随意使用常规的 html 元素

<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>

【讨论】:

非常感谢,我现在真的明白了。此外,当登录成功时,我看到您保存访问令牌以供将来请求,但用户是否已登录?你如何用你的警卫保护你的路线?我如何告诉 laravel 我的用户已登录? 抱歉这么晚才回复。要告诉 laravel 用户已登录,您必须将用户 access_token 传递给 http 请求的标头。由于您已将 access_token 保存在 localStorage 上,因此您可以访问并将其放入标头。 Vuex 商店将是这种场景的最佳选择。如果您需要有关如何实现它的指导,请告诉我。 这正是我要理解的一些问题。现在为了使它工作,当检索到 access_token 时,我获取用户并使用 Auth::login($user)。我猜这是错误的,因为我使用数据库。我知道当我获得 access_token 时,我可以使用标头并执行 http 请求,但是我如何告诉 laravel 会话我使用中间件('auth')登录。

以上是关于使用外部 Laravel 护照流明 api 进行 Laravel 客户端身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Laravel/流明 api 过滤器

身份验证用户提供程序 [passport] 未使用 laravel 护照定义

Laravel 护照公共 api 路线

Laravel 流明版本控制

laravel 6护照中未经授权的401错误

在 laravel 护照中注销用户