基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录 | 构建 API 接口:GraphQL | Laravel 入门到精通教程


本站和网页 https://xueyuanjun.com/post/9283.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录 | 构建 API 接口:GraphQL | Laravel 入门到精通教程
Laravel 学院
文档
Laravel 8.x 中文文档
Laravel 7.x 中文文档
Laravel 6.x 中文文档
Laravel 5.8 中文文档
Laravel 5.7 中文文档
Laravel 5.6 中文文档
Laravel 5.5 中文文档
Laravel 5.4 中文文档
Laravel 5.3 中文文档
Laravel 5.2 中文文档
Laravel 5.1 中文文档
Lumen 中文文档
全栈教程
PHP 全栈工程师指南
PHP 入门到实战
Laravel 入门到精通
Vue.js 入门到实战
玩转 PhpStorm 教程
Laravel 博客入门项目
Laravel 微信小程序项目
Laravel 前后端分离项目
Swoole 入门到实战
Eloquent 性能优化实战
Redis 高性能实战系列
Laravel 新版本特性
PHP 新特性与最佳实践
Golang
Go 入门教程
Go Web 编程
Gin 使用教程
微服务开发
内功修炼
数据结构与算法
网络协议
微服务从入门到实践
高性能 MySQL 实战
高性能 Redis 实战
Laravel 消息队列实战
Laravel 从学徒到工匠
PHP 设计模式系列
名企面试指南
资源库
Laravel 资源大全
Laravel 开源项目
Laravel 扩展包
Laravel 资源下载
更多
博客 & 新闻
问答 & 讨论
Leetcode 题解
学院君读书笔记系列
关于 Laravel 学院
Laravel 互助学习群
Golang 互助学习群
更多
Laravel 中文文档
Laravel 全栈教程
Laravel 学习路径
Go 入门教程
程序员内功修炼
博客
问答
搜索
注册
登录
Info
Content
章节导航
Laravel 入门到精通教程
目录索引
开发环境篇
8篇文章
通过 Sail 构建基于 Docker 的 Laravel 本地集成开发环境
通过 Homestead 构建基于 Vagrant 的 Laravel 本地集成开发环境
通过 Valet 在 Mac 系统构建轻量级 Laravel 本地集成开发环境
Mac 系统为 Valet 开发环境安装指定版本 MySQL
在 Mac/Windows 系统中使用 Laradock 搭建基于 Docker 的 Laravel 开发环境
使用 Laragon 在 Windows 中快速搭建 Laravel 本地开发环境
使用 Visual Studio Code 作为 Laravel 开发工具
创建并运行一个新的 Laravel 项目
路由&控制器篇
5篇文章
Laravel 路由入门:路由定义、参数传递及路由命名
Laravel 路由分组规则:中间件、子域名、路由前缀和命名空间
Laravel 控制器:从 MVC 模式到资源控制器
路由进阶使用:模型绑定、兜底路由、频率限制和路由缓存
表单方法伪造与跨站请求伪造(CSRF)攻击防护
视图模板篇
4篇文章
视图入门:Laravel 支持的视图格式以及在路由中的基本使用
Blade 模板引擎入门篇:数据渲染 & 控制结构
Blade 模板引擎进阶篇:模板继承 & 组件引入
Blade 模板引擎高级篇:View Composer & 自定义指令
前端入门篇
3篇文章
在 Laravel 项目中使用 Bootstrap 框架
CSS 预编译语言 Sass 快速入门教程
在 Laravel 项目中编写第一个 Vue 组件
请求处理篇
5篇文章
通过 Request 对象实例获取用户请求数据
基于 Laravel + Vue 组件实现文件异步上传
在 Laravel 控制器中进行表单请求字段验证
通过表单请求类实现请求字段验证和错误提示
通过匿名函数和验证规则类自定义字段验证规则
命令行交互篇
3篇文章
在 Laravel 中编写第一个 Artisan 命令
在 Laravel 中编写高级的 Artisan 命令
通过 Tinker 实现 Laravel 命令行交互式 Shell
数据库与 Eloquent 模型
16篇文章
入门篇(一):数据库连接配置和读写分离
入门篇(二):通过迁移文件定义数据表结构
入门篇(三):通过填充器快速填充测试数据
入门篇(四):通过查询构建器实现简单的增删改查操作
进阶篇(一):通过查询构建器实现复杂的查询语句
进阶篇(二) —— 通过 Eloquent 模型实现简单增删改查操作
进阶篇(三):通过 Eloquent 模型实现批量赋值和软删除
进阶篇(四):在 Eloquent 模型类上设置访问器和修改器
进阶篇(五):在 Eloquent 模型类上使用全局作用域和局部作用域进行查询
进阶篇(六):Eloquent 模型事件和监听方式大全
进阶篇(七):Eloquent 模型关联关系(上)
进阶篇(八):Eloquent 模型关联关系(中)
进阶篇(九):Eloquent 模型关联关系(下)
结合 Bootstrap + Vue 组件在 Laravel 中实现异步分页功能
在 Laravel 中通过自定义分页器分页方法实现伪静态分页链接以利于 SEO
基于 Laravel + Vue 构建一个类似 Twitter 的 Web 应用
用户认证与授权
19篇文章
使用 Entrust 扩展包在 Laravel 5 中实现 RBAC 权限管理(一):安装配置篇
使用 Entrust 扩展包在 Laravel 5 中实现 RBAC 权限管理(二):使用篇
基于 Laravel Permission 扩展包在项目中轻松实现 RBAC 权限管理功能
通过内置脚手架快速实现用户认证
用户注册登录流程及多字段登录实现
基于多表的用户认证功能实现(前后台用户)
通过 Passport 实现 API 请求认证:单页面应用篇
通过 Passport 实现 API 请求认证:移动端应用篇(密码授权令牌)
通过 Passport 实现 API 请求认证:第三方应用篇(授权码获取令牌)
通过 Passport 实现 API 请求认证:开放平台篇(客户端凭证令牌)
通过 Passport 实现 API 请求认证:沙箱测试篇(私人访问令牌)
通过 Passport 实现 API 请求认证:隐式授权令牌
通过 Passport 实现 API 请求认证:令牌作用域详解
通过 Laravel 内置脚手架快速实现邮箱验证功能
通过监听注册登录、邮箱验证事件实现简单的积分功能
通过 Cookie 实现基于 Session 的单点登录
基于 CAS 实现通用的单点登录解决方案(一):CAS 原理及服务端搭建
基于 CAS 实现通用的单点登录解决方案(二):CAS 客户端搭建及单点登录测试
基于 CAS 实现通用的单点登录解决方案(三):用户单点退出实现
请求响应底层剖析
8篇文章
Laravel 底层是如何处理 HTTP 请求的
Laravel 请求类 Request 剖析
Laravel 响应类 Response 剖析
Laravel 中间件底层源码剖析
Laravel 路由匹配和执行底层源码剖析
异常处理篇之底层源码剖析
异常处理篇之异常信息报告、渲染及自定义处理
Laravel 框架如何基于 Composer 实现类和文件的自动加载
测试驱动开发
12篇文章
从基于 PHPUnit 编写单元测试开始
在 Laravel 中基于 PHPUnit 进行代码测试:目录结构及测试编排文件 phpunit.xml 详解
在 Laravel 中基于 PHPUnit 进行代码测试:单元测试篇
在 Laravel 中基于 PHPUnit 进行代码测试:HTTP 测试篇(上)
在 Laravel 中基于 PHPUnit 进行代码测试:HTTP 测试篇(下)
在 Laravel 中基于 Dusk 实现浏览器自动化测试快速入门
通过测试驱动开发构建待办任务项目(一):后端接口和功能测试篇
通过测试驱动开发构建待办任务项目(二):前端功能和浏览器测试篇
持续集成的定义和常用 CI 系统对比
基于 Github + CircleCI 实现 Laravel 项目的持续集成
基于 Github + Travis CI 实现 Laravel 项目的持续集成
基于 Coding + Jenkins 实现 Laravel 项目的持续集成
构建 API 接口:原生开发
5篇文章
编写 JSON API —— RESTful 风格 API 设计原则与最佳实践
编写 JSON API —— 基于资源控制器和 API 资源类快速构建 API 接口
Laravel API 系列教程(一): 基于 Laravel 5.5 构建 & 测试 RESTful API
Laravel API 系列教程(二): 结合 Laravel 5.5 和 Vue SPA 基于 jwt-auth 实现 API 认证
Laravel API 系列教程(三):使用 API Resource 来创建自己的 {JSON:API} 格式 API
构建 API 接口:GraphQL
6篇文章
Laravel API 系列教程(四):基于 GraphQL 构建 Laravel API —— 基本使用篇
Laravel API 系列教程(五):基于 GraphQL 构建 Laravel API —— 高级使用篇
解决前后端分离应用跨域请求利器 —— Laravel CORS 扩展包
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(二) —— 用户列表及详情页
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(三) —— 文章发布及浏览
构建 API 接口:Dingo API
12篇文章
使用 Dingo API 快速构建 RESTful API(一)—— 安装配置篇
使用 Dingo API 快速构建 RESTful API(二)—— 编写第一个 API 接口
使用 Dingo API 快速构建 RESTful API(三)—— 返回基本 JSON 响应
使用 Dingo API 快速构建 RESTful API(四)—— 转化器篇(上):Fractal 简介及其使用入门
使用 Dingo API 快速构建 RESTful API(五)—— 转化器篇(下):结合响应构建器构建 JSON 响应
使用 Dingo API 快速构建 RESTful API(六)—— 转化器及响应构建器的高级使用
使用 Dingo API 快速构建 RESTful API(七)—— 错误及异常处理
使用 Dingo API 快速构建 RESTful API(八)—— API 认证实现(上)
使用 Dingo API 快速构建 RESTful API(九)—— API 认证实现(下)
使用 Dingo API 快速构建 RESTful API(十)—— 路由访问频率限制
使用 Dingo API 快速构建 RESTful API(十一)—— 在应用内部请求 Dingo API
使用 Dingo API 快速构建 RESTful API(十二)—— 生成 API 文档
构建 API 接口:生成 API 文档
3篇文章
使用 Laravel API 文档生成器扩展包自动为项目生成 API 文档
在 Laravel 中集成 API 文档生成器扩展包为 Dingo API 接口生成文档
在 Laravel 项目中集成 Swagger 扩展包为 Laravel API 生成接口文档并对接口进行测试
系统组件
4篇文章
基于 Laravel + Pusher + Vue 通过事件广播构建实时聊天室应用
由浅入深:基于 Laravel Broadcast 实现 WebSocket C/S 实时通信
基于迅搜(xunsearch) + Laravel Scout 实现 Laravel 学院全文搜索功能(支持多模型搜索)
基于七牛云 PHP SDK + Laravel 文件存储实现 Laravel 学院静态资源云存储及 CDN 加速
图书
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(一) —— 用户注册登录
由 学院君 创建于4年前, 最后更新于 3年前
版本号 #1
40450 views
9 likes
0 collects
概述
今天开始,学院君将通过三篇教程的篇幅来系统介绍如何基于 Laravel + Vue 实现一个简单的、带用户认证的、前后端分离的博客应用,同时趁热打铁地将 GraphQL 融入进来实现 API 构建 —— Laravel 作为 GraphQL 服务端为前端 Vue 应用提供 API 接口。
前端应用初始化
后端 Laravel 应用我们以前面地 API 系列教程中使用的 apidemo.test 为基础,不再赘述 Laravel 应用安装配置及 GraphQL 扩展包安装和使用。这里,我们花一点时间来演示前端 Vue 应用的安装和初始化。
在 Web 服务器根目录下(与 Laravel 应用目录平级)通过以下命令初始化安装 Vue 应用:
npm install -g vue-cli // 已全局安装过 vue-cli 略过此步骤
vue init webpack graphql-blog-app
应用初始化过程中命令行会有一系列交互,按照默认的选项一路回车即可:
初始化完成后,进入 Vue 应用根目录并安装博客应用所需依赖:
cd graphql-blog-app
npm install --save vue-apollo@next graphql apollo-client apollo-link apollo-link-context apollo-link-http apollo-cache-inmemory graphql-tag
我们来看一下上面的每个依赖是干嘛的:
vue-apollo:在 Vue 中集成 Apollo/GraphQL 支持;
graphql:JavaScript 中的 GraphQL 实现;
apollo-client:Apollo GraphQL 客户端,允许你轻松构建通过 GraphQL 获取数据的 UI 组件;
apollo-link:获取/修改 GraphQL 请求和结果控制流的接口
apollo-link-context:用于设置操作上下文
apollo-link-http:基于 HTTP 通过网络请求获取 GraphQL 结果
apollo-cache-inmemory:Apollo 客户端缓存实现
graphql-tag:用于解析 GraphQL 查询的 JavaScript 模板语义标签
设置 Vue Apollo
通过上述安装的依赖可以看到,在 Vue 中我们是通过 Apollo 相关扩展包实现与 GraphQL 服务端的交互。下面我们将使用这些扩展包构建所需的功能,打开 Vue 应用下的 src/main.js 文件,添加如下代码:
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
const httpLink = new HttpLink({
// GraphQL 服务器 URL,需要使用绝对路径
uri: 'http://apidemo.test/graphql'
})
// 创建 apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
// 安装 vue plugin
Vue.use(VueApollo)
我们通过 GraphQL 服务端 URL 创建了一个新的 httpLink 实例,然后使用这个 httpLink 实例创建 Apollo 客户端,并指定使用内存缓存,最后安装 Vue Apollo 插件。
接下来创建一个 apolloProvider 对象并将其传入应用根组件:
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
apolloProvider,
components: { App },
template: '<App/>'
})
最终我们的 src/main.js 文件应该是这样子:
import Vue from 'vue'
import App from './App'
import router from './router'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
Vue.config.productionTip = false
const httpLink = new HttpLink({
// URL to graphql server, you should use an absolute URL here
uri: 'http://apidemo.test/graphql'
})
// create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
// install the vue plugin
Vue.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
apolloProvider,
template: '<App/>',
components: { App }
})
引入 Bulma CSS
博客应用前端视图层使用 Bulma CSS,在 index.html 中引入即可:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>GraphQL 博客</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
添加主布局
博客会在不同页面使用共用的布局,这个主布局组件就是位于 src 目录下地 App.vue,更新其代码如下:
<template>
<div id="app">
<nav class="navbar is-primary" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<router-link class="navbar-item" to="/">GraphQL 博客</router-link>
<button class="button navbar-burger">
<span></span>
<span></span>
<span></span>
</button>
</div>
</div>
</nav>
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
</script>
我们在其中定义了所有页面都会共用的顶部导航条。
用户注册功能实现
定义完前端应用所需的基础组件后,接下来我们来逐步实现博客应用包含的所有功能:
用户注册
用户登录
用户列表
用户详情
发布文章
应用首页
文章详情
我们大概围绕这几个模块实现博客功能,首先从用户注册开始。
后端注册接口
在开始之前,我们假设你已经看过学院前面的 API 系列教程二(基于 jwt-auth 实现 API 认证)和教程四(GraphQL 在 Laravel 中的配置&使用)并编写好相关代码,我们将在其基础上进行编码工作。
在 Laravel 应用根目录下执行以下 Artisan 命令创建新的 Mutation:
php artisan make:graphql:mutation SignupMutation
然后编辑刚生成的 SignupMutation 类代码如下:
namespace App\GraphQL\Mutation;
use App\User;
use Folklore\GraphQL\Support\Mutation;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use GraphQL;
class SignupMutation extends Mutation
protected $attributes = [
'name' => 'Signup',
'description' => 'A mutation for user sign up'
];
public function type()
return GraphQL::type('User');
public function args()
return [
'name' => ['name' => 'name', 'type' => Type::nonNull(Type::string())],
'email' => ['name' => 'email', 'type' => Type::nonNull(Type::string())],
'password' => ['name' => 'password', 'type' => Type::nonNull(Type::string())]
];
public function rules()
return [
'name' => ['required', 'unique:users'],
'email' => ['required', 'email', 'unique:users'],
'password' => ['required', 'min:6'],
];
public function resolve($root, $args, $context, ResolveInfo $info)
$user = new User();
$user->name = $args['name'];
$user->email = $args['email'];
$user->password = bcrypt($args['password']);
$user->save();
return $user;
在 config/graphql.php 中注册刚刚创建的 Mutation:
'schemas' => [
'default' => [
'query' => [
... // 所有 Query
],
'mutation' => [
... // 其它 Mutation
'createUser' => \App\GraphQL\Mutation\SignupMutation::class,
],
接下来就可以在 GraphiQL 中测试这个接口了,我们先测试下字段验证:
验证失败会在结果中返回每个字段对应的错误信息。如果注册接口调用成功,返回信息如下:
前端注册组件
定义 GraphQL Mutaion
在正式编写前端代码之前需要先创建一个用于处理所有 GraphQL 查询和变更的全局文件,我们在 src 目录下新增一个 graphql.js 文件来处理这些逻辑,首先定义一段用于处理用户注册的语句:
import gql from 'graphql-tag'
export const SIGNUP_MUTATION = gql`
mutation SignupMutation($name: String!, $email: String!, $password: String!) {
createUser(
name: $name,
email: $email,
password: $password
) {
id
name
email
创建 SignUp 组件
接下来在 src/components 目录下新增 Admin 子目录,并在 Admin 目录下创建 SignUp 组件 SignUp.vue:
<template>
<section class="section">
<div class="columns">
<div class="column is-4 is-offset-4">
<h2 class="title has-text-centered">用户注册</h2>
<form method="POST" @submit.prevent="signup">
<div class="field">
<label class="label">用户名</label>
<p class="control">
<input
type="text"
class="input"
v-model="name">
</p>
</div>
<div class="field">
<label class="label">邮箱</label>
<p class="control">
<input
type="email"
class="input"
v-model="email">
</p>
</div>
<div class="field">
<label class="label">密码</label>
<p class="control">
<input
type="password"
class="input"
v-model="password">
</p>
</div>
<p class="control">
<button class="button is-primary is-fullwidth is-uppercase">注册</button>
</p>
</form>
</div>
</div>
</section>
</template>
<script>
import { SIGNUP_MUTATION } from '@/graphql'
export default {
name: 'SignUp',
data () {
return {
name: '',
email: '',
password: ''
},
methods: {
signup () {
this.$apollo
.mutate({
mutation: SIGNUP_MUTATION,
variables: {
name: this.name,
email: this.email,
password: this.password
})
.then(response => {
// 重定向到登录页面
this.$router.replace('/login')
})
</script>
该组件用于渲染一个简单的、用于用户注册的表单。用户点击注册按钮后会调用 signup 方法,在该方法中我们可以使用 this.$apollo (Vue Apollo 插件)上的 mutate 方法,通过前面创建的 SIGNUP_MUTATION 将参数传递到 GraphQL 服务端(即我们的 Laravel 应用),用户注册成功后就会跳转到 /login 页面。
添加注册路由
打开 src/router/index.js,更新代码如下新增 /signup 路由:
import Vue from 'vue'
import Router from 'vue-router'
import SignUp from '@/components/Admin/SignUp'
Vue.use(Router)
export default new Router({
routes: [
path: '/signup',
name: 'SignUp',
component: SignUp
})
这样我们就可以通过 /signup 路由访问注册页面了。
在浏览器访问 Vue 应用
有两种方式在浏览器中实现对 Vue 应用的访问,一种是通过在 Vue 应用根目录下通过运行如下命令:
npm run dev
这样就可以在通过 http://localhost:8080 (具体端口以命令行提示为准,有可能是 8081)以开发环境模式访问应用,这样做的好处是可以方便代码调试,建议在代码调试及本地测试阶段使用这种方式访问应用。
还有一种方式是在 Nginx 中配置站点通过域名方式进行访问,建议代码调试无误后使用这种方式访问,生产环境也是通过这种方式访问应用。在代码测试通过后,在应用根目录下运行如下命令:
npm run build
该命名会对前端代码进行编译并将编译后代码放到新生成地 dist 目录下,所以我们在 Nginx 中对前端应用配置如下:
server {
listen 80;
listen [::]:80;
server_name apollo-blog.test;
root /var/www/graphql-blog-app/dist;
index index.html index.htm;
location / {
try_files $uri $uri/ @rewrites;
location @rewrites {
rewrite ^(.+)$ /index.html last;
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
# Some basic cache-control for static files to be sent to the browser
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
配置完成后运行对 Nginx 服务进行 reload,然后在 /etc/hosts 中进行域名绑定:
127.0.0.1 apollo-blog.test
这种方式需要每次代码变动后重新运行 npm run build,所以适合代码稳定(如生产环境
)后部署。
按照以上步骤配置完成后,通过 http://apollo-blog.test/#/signup(或者http://localhost:8080/#/signup) 即可访问注册页面:
允许跨域请求
这时候我们填写表单后点击注册按钮还不能访问后端接口,因为前后端分离之后带来的一个问题是前后端域名不一样,由于浏览器的同源策略,前端无法跨域请求后端接口,为了解决这个问题,我们在后端使用 CORS 解决方案以支持跨域请求,关于该方案原理及使用明细可以参考Laravel CORS 扩展包教程,这里不再赘述,我们只需在 Laravel 后端应用的配置文件 config/graphql.php 中做如下中间件配置即可:
'middleware_schema' => [
'default' => [
\Barryvdh\Cors\HandleCors::class,
],
],
这样,我们就可以通过注册表单注册新用户了。
用户登录功能实现
后端登录接口
在 Laravel 应用根目录下运行以下 Artisan 命令生成登录 Mutation 类:
php artisan make:graphql:mutation LoginMutation
编辑刚生成的 LoginMutation 类代码如下:
namespace App\GraphQL\Mutation;
use Folklore\GraphQL\Error\AuthorizationError;
use Folklore\GraphQL\Support\Mutation;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use GraphQL;
use JWTAuth;
use Auth;
class LoginMutation extends Mutation
protected $attributes = [
'name' => 'Login',
'description' => 'A mutation for user login'
];
public function type()
return GraphQL::type('User');
public function args()
return [
'email' => ['name' => 'email', 'type' => Type::nonNull(Type::string())],
'password' => ['name' => 'password', 'type' => Type::nonNull(Type::string())],
];
public function rules()
return [
'email' => ['required', 'email'],
'password' => ['required']
];
public function resolve($root, $args, $context, ResolveInfo $info)
$credentials = [
'email' => $args['email'],
'password' => $args['password']
];
if (!$token = JWTAuth::attempt($credentials)) {
throw new AuthorizationError('Invalid Credentials.');
$user = Auth::user();
$user->token = $token;
return $user;
在 UserType 的 fields 方法中新增返回字段 token:
'token' => [
'type' => Type::string(),
'description' => 'The token of the user',
],
最后在 config/graphql.php 中注册刚编写的 LoginMutation:
'schemas' => [
'default' => [
'query' => [
... // 所有 Query
],
'mutation' => [
... // 其它 Mutation
'login' => \App\GraphQL\Mutation\LoginMutation::class,
],
接下来先在 GraphiQL 中对接口进行测试,邮箱密码验证失败返回结果如下:
邮箱密码验证成功返回登录用户信息(含token):
前端登录组件
定义 GraphQL Mutation
首先还是在 Vue 应用的 src/graphql.js 中为用户登录定义 GraphQL 操作语句:
export const LOGIN_MUTATION = gql`
mutation LoginMutation($email: String!, $password: String!) {
login(
email: $email,
password: $password
) {
id
name
email
token
创建登录组件
接下来在 components/Admin 目录下创建一个登录组件 LogIn.vue,并编写组件代码如下:
<template>
<section class="section">
<div class="columns">
<div class="column is-4 is-offset-4">
<h2 class="title has-text-centered">用户登录</h2>
<form method="POST" @submit.prevent="login">
<div class="field">
<label class="label">邮箱</label>
<p class="control">
<input
type="email"
class="input"
v-model="email">
</p>
</div>
<div class="field">
<label class="label">密码</label>
<p class="control">
<input
type="password"
class="input"
v-model="password">
</p>
</div>
<p class="control">
<button class="button is-primary is-fullwidth is-uppercase">登录</button>
</p>
</form>
</div>
</div>
</section>
</template>
<script>
import { LOGIN_MUTATION } from '@/graphql'
export default {
name: 'LogIn',
data () {
return {
email: '',
password: ''
},
methods: {
login () {
this.$apollo
.mutate({
mutation: LOGIN_MUTATION,
variables: {
email: this.email,
password: this.password
})
.then(response => {
// 保存用户 token 到 local storage
localStorage.setItem('blog-app-token', response.data.login.token)
// 重定向用户到文章列表页
this.$router.replace('/admin/posts')
})
</script>
该组件用于渲染一个简单的用户登录表单,表单提交后就会调用 login 方法,在 login 方法中我们可以使用 mutate 方法来完成 LOGIN_MUTATION 操作;登录成功之后,将从 GraphQL 服务器获取到的 token 保存到 localstorage 并将用户重定向到后台文章列表页面。
添加登录路由
打开 src/router/index.js 文件,将下面的代码插入到合适的位置:
import LogIn from '@/components/Admin/LogIn'
// 将这段代码放到 `routes` 数组内
path: '/login',
name: 'LogIn',
component: LogIn
},
测试登录功能
通过 http://localhost:8080/#/login 确认代码无误后,运行 npm run build 然后在浏览器访问 http://apollo-blog.test/#/login 页面:
我们使用前面注册的用户信息登录,登录成功后可以通过在浏览器 F12 查看保存在 Local Storage 的 token 信息:
后续我们将通过在每次请求时在请求头中传递该 token 信息以实现用户认证。
本篇至此结束,下篇教程我们将围绕后台用户列表和用户详情页展开。
Laravel
路由
登录
注册
博客
API
JWT
组件
Vue
GraphQL
CORS
跨域请求
Apollo
前后端分离
Bulma
点赞
取消点赞
收藏
取消收藏
赞赏
分享到以下平台:
<< 上一篇:
解决前后端分离应用跨域请求利器 —— Laravel CORS 扩展包
>> 下一篇:
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(二) —— 用户列表及详情页
18 条评论
#11
krelvis
评论于 4年前
回复 #8
正在删除评论...
我也想知道!
#12
学院君
评论于 4年前
回复 #11
正在删除评论...
用户名下没有下划线的是不存在于系统中的用户 是之前wp通过填写邮箱提交的评论
#13
大漠胡杨
评论于 4年前
正在删除评论...
LoginMutation 中
应将
use JWTAuth;
use Auth;
改为:
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Auth;
#14
学院君
评论于 4年前
回复 #13
正在删除评论...
那是你没有在 config/app.php 中注册Facade吧
#15
mutou
评论于 4年前
正在删除评论...
"data": null,
"errors": [
"message": "Variable \"$name\" of required type \"String!\" was not provided.",
"locations": [
"line": 1,
"column": 25
请问这个问题如何解决呢
#16
k2a4LCDL1ONZSy
评论于 4年前
正在删除评论...
npm install -g vue 之后提示 vue 命令找不到,
使用 npm install -g vue-cli 之后 vue 命令可以使用,怎么回事(꒦_꒦)
#17
学院君
评论于 4年前
回复 #16
正在删除评论...
按照官方文档是应该安装 vue-cli 不过我在 linux 下安装 vue 也是可以的 我改下吧
#18
MonkWong
评论于 2年前
正在删除评论...
folklore/graphql 这个包已经被抛弃了,“This package is abandoned and no longer maintained. No replacement package was suggested.”
&lsaquo;
&rsaquo;
登录后即可添加评论
升级为学院君订阅用户(新年优惠🎁)
内容导航
概述
前端应用初始化
设置 Vue Apollo
引入 Bulma CSS
添加主布局
用户注册功能实现
后端注册接口
前端注册组件
允许跨域请求
用户登录功能实现
后端登录接口
前端登录组件
相关推荐
Laravel API 系列教程(二): 结合 Laravel 5.5 和 Vue SPA 基于 jwt-auth 实现 API 认证
Laravel 入门到精通教程
构建 API 接口:原生开发
解决前后端分离应用跨域请求利器 —— Laravel CORS 扩展包
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(二) —— 用户列表及详情页
Laravel 入门到精通教程
构建 API 接口:GraphQL
基于 Laravel + Vue + GraphQL 实现前后端分离的博客应用(三) —— 文章发布及浏览
Laravel 入门到精通教程
构建 API 接口:GraphQL
通过 Vue 组件、Vue Router、Vuex 和 Laravel 实现表单提交
基于 Laravel + Vue 构建前后端分离应用
Vuex & Vue Router 使用入门:表单提交
回到顶部
2022 基于 Laravel 6 构建
关于学院
订阅服务
友情链接
站点地图
本站 CDN 加速服务由又拍云赞助