在 Linux 配置基于 Laravel 的小程序开发环境
安装环境
任务时间:5min ~ 10min
更新操作系统
首先,我们需要更新我们的操作系统,让我们的云主机处在最新的状态。执行如下命令
yum update -y
安装 Apache 、 PHP 、 MySQL
完成了系统的更新后,我们来配置服务器端的 LAMP(Linux、Apache、MySQL、PHP)环境,让我们的 Laravel 可以在云端运行。
安装 Apache
首先,我们来安装 Apache ,执行如下命令:
yum -y install httpd
稍等片刻后,安装完成,执行如下命令来启动 Apache 服务,并配置开机自启动
systemctl start httpd.service
systemctl enable httpd.service
这时,你可以执行如下命令来检测你的 Apache 是否正常工作
curl <您的 CVM IP 地址>
安装 MySQL
接下来,来执行命令配置 MySQL 环境
yum -y install mariadb-server mariadb
稍等片刻后,安装完成,执行如下命令启动 Mariadb
systemctl start mariadb
然后执行如下命令来进行数据库的初始化
mysql_secure_installation
执行命令后,会让你输入默认的用户名,这里默认为空,直接回车即可,
提示设置 Root 密码时,选择 Y ,并输入 Root 密码,确认。
提示移除匿名用户时,选择 Y
提示关闭远程的 root 登录时,选择 Y
提示删除测试数据库时,选择 Y
提示刷新权限数据库时,选择 Y
这样,我们就完成了 MySQL 数据库的安全初始化了。
然后,执行如下命令,让 MySQL 开机自启动
systemctl start mariadb
安装 PHP 7
接下来,我们来安装 PHP 7 ,这里我们需要借助 webtatic 库编译的源码。
执行如下命令,来安装 webtatic 库
yum -y install epel-release
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
稍等片刻,安装完成后,我们可以执行命令来安装 PHP7
yum install -y php70w php70w-opcache php70w-mysql php70w-mcrypt php70w-dom php70w-mbstring unzip
稍等片刻,模块就安装完成了,我们重启一下 Apache
systemctl restart httpd
安装 Composer
Laravel 使用 Composer 来管理依赖,所以,我们需要在我们的服务端配置上 Composer .执行如下命令,来安装 Composer
curl -k -sS https://getcomposer.org/installer | php
echo $PATH
mv composer.phar /usr/local/bin/composer
安装完成后,执行如下命令,切换为国内镜像,加速后续依赖的下载
composer config -g repo.packagist composer https://packagist.laravel-china.org
安装 Laravel
任务时间:5min ~ 10min
初始化项目
接下来,我们在 Apache 的根目录中创建一个 Laravel 项目
cd /var/www/html
composer create-project --prefer-dist laravel/laravel ./
chown apache:apache -R /var/www/html
执行完成命令后,会自动在当前目录的根目录中看到各文件。此时,可以访问 http://<您的 CVM IP 地址>/public 查看默认首页。
移除默认的 /public
我们在访问时,有一个 public 的前缀,非常不好看,我们希望可以去除这个前缀。
参考下面的配置文件,创建你的虚拟主机配置文件(/etc/httpd/conf.d/laravel.conf)
示例代码:/etc/httpd/conf.d/laravel.conf
<VirtualHost *:80>
DocumentRoot /var/www/html/public
ServerName <您的 CVM IP 地址>
<Directory /var/www/html/>
AllowOverride All
</Directory>
</VirtualHost>
保存完成后,重启 Apache .
systemctl restart httpd
然后,就可以访问 http://<您的 CVM IP 地址> 查看 Laravel 的默认页面了。
链接微信
任务时间:15min ~ 20min
引入 EasyWeChat
这里,我们使用 EasyWeChat 作为我们的微信框架,进入到我们的项目根目录,执行如下命令来安装 EasyWeChat
cd /var/www/html/
composer require "overtrue/laravel-wechat:~4.0"
稍等片刻,执行完成后,执行如下命令
php artisan vendor:publish --provider="OvertrueLaravelWeChatServiceProvider"
会自动生成 config/wechat.php ,接下来,我们来编辑这个文件,将其中代码改为如下所示(取消小程序部分和微信支付部分的注释)。
<?php
/*
* This file is part of the overtrue/laravel-wechat.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
return [
/*
* 默认配置,将会合并到各模块中
*/
'defaults' => [
/*
* 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
*/
'response_type' => 'array',
/*
* 使用 Laravel 的缓存系统
*/
'use_laravel_cache' => true,
/*
* 日志配置
*
* level: 日志级别,可选为:
* debug/info/notice/warning/error/critical/alert/emergency
* file:日志文件位置(绝对路径!!!),要求可写权限
*/
'log' => [
'level' => env('WECHAT_LOG_LEVEL', 'debug'),
'file' => env('WECHAT_LOG_FILE', storage_path('logs/wechat.log')),
],
],
/*
* 路由配置
*/
'route' => [
/*
* 开放平台第三方平台路由配置
*/
// 'open_platform' => [
// 'uri' => 'serve',
// 'action' => OvertrueLaravelWeChatControllersOpenPlatformController::class,
// 'attributes' => [
// 'prefix' => 'open-platform',
// 'middleware' => null,
// ],
// ],
],
/*
* 公众号
*/
'official_account' => [
'default' => [
'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', 'your-app-id'), // AppID
'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', 'your-app-secret'), // AppSecret
'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'your-token'), // Token
'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''), // EncodingAESKey
/*
* OAuth 配置
*
* scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
* callback:OAuth授权完成后的回调页地址(如果使用中间件,则随便填写。。。)
*/
// 'oauth' => [
// 'scopes' => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
// 'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/examples/oauth_callback.php'),
// ],
],
],
/*
* 开放平台第三方平台
*/
// 'open_platform' => [
// 'default' => [
// 'app_id' => env('WECHAT_OPEN_PLATFORM_APPID', ''),
// 'secret' => env('WECHAT_OPEN_PLATFORM_SECRET', ''),
// 'token' => env('WECHAT_OPEN_PLATFORM_TOKEN', ''),
// 'aes_key' => env('WECHAT_OPEN_PLATFORM_AES_KEY', ''),
// ],
// ],
/*
* 小程序
*/
'mini_program' => [
'default' => [
'app_id' => env('WECHAT_MINI_PROGRAM_APPID', ''),
'secret' => env('WECHAT_MINI_PROGRAM_SECRET', ''),
'token' => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),
],
],
/*
* 微信支付
*/
'payment' => [
'default' => [
'sandbox' => env('WECHAT_PAYMENT_SANDBOX', false),
'app_id' => env('WECHAT_PAYMENT_APPID', ''),
'mch_id' => env('WECHAT_PAYMENT_MCH_ID', 'your-mch-id'),
'key' => env('WECHAT_PAYMENT_KEY', 'key-for-signature'),
'cert_path' => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'), // XXX: 绝对路径!!!!
'key_path' => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'), // XXX: 绝对路径!!!!
'notify_url' => 'http://example.com/payments/wechat-notify', // 默认支付结果通知地址
],
// ...
],
/*
* 企业微信
*/
// 'work' => [
// 'default' => [
// 'corp_id' => 'xxxxxxxxxxxxxxxxx',
/// 'agent_id' => 100020,
// 'secret' => env('WECHAT_WORK_AGENT_CONTACTS_SECRET', ''),
// //...
// ],
// ],
];
然后,我们在 /var/www/html/.env 文件中添加如下代码
WECHAT_MINI_PROGRAM_APPID=
WECHAT_MINI_PROGRAM_SECRET=
WECHAT_MINI_PROGRAM_TOKEN=
WECHAT_MINI_PROGRAM_AES_KEY=
WECHAT_PAYMENT_SANDBOX=false
WECHAT_PAYMENT_APPID=
WECHAT_PAYMENT_MCH_ID=
WECHAT_PAYMENT_KEY=
WECHAT_PAYMENT_CERT_PATH=
WECHAT_PAYMENT_KEY_PATH=
并将各项目设置成为我们自己的值,后续,我们将使用 .env 文件中的值来创建小程序实例,并使用这个小程序实例来进行微信登录等后续的代码。
引入 JWT Auth
接下来,我们在项目内引入 JWT Auth
cd /var/www/html
composer require tymon/jwt-auth 1.0.0-rc.2
然后执行如下命令生成配置文件
php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"
并生成 Secret
php artisan jwt:secret
然后,修改一下我们的配置文件(config/auth.php),你可以点击下面的对比查看具体的修改内容。
示例代码:/var/www/html/config/auth.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
并修改我们的 app/User.php 文件
示例代码:/var/www/html/app/User.php
<?php
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
这样我们就完成了 JWT Auth 的引入,后续,我们将返回 JWT 的 Token 给小程序,用于后续的登录。
创建 Auth 控制器,并实现微信登录
引入 Auth Controller
接下来,我们来生成一个 Auth 控制器,用于我们的微信登录
cd /var/www/html
php artisan make:controller AuthController
示例代码:/var/www/html/app/Http/Controllers/AuthController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function me()
{
return response()->json(auth()->user());
}
public function logout()
{
auth()->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken(auth()->refresh());
}
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
}
并且,在 routes/api.php 中添加如下代码
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function ($router) {
Route::post('login', 'AuthController@login');
Route::post('logout', 'AuthController@logout');
Route::post('refresh', 'AuthController@refresh');
Route::post('me', 'AuthController@me');
});
改造微信登录
接下来,我们将 AuthController 中的 Login 方法修改为 微信登录的机制。
首先,在文件顶部添加如下代码(点我编辑文件)
use EasyWeChat;
use IlluminateHttpRequest;
然后替换 Login 方法为如下代码
public function login(Request $request)
{
$miniProgram = EasyWeChat::miniProgram();
/**
* 换取 Session Key
*/
$session_data = $miniProgram->auth->session($request->code);
$username = $session_data['openId']."@cloud.tencent.com";
$password = $session_data['openId'];
$credentials = [
'email' => $username,
'password' => $password
];
/**
* 检测用户信息是否可以登录
* 如果可以登录,则说明已经有相关用户
* 如果不可以登录,则跳转到创建用户的逻辑
*/
if (! $token = auth()->attempt($credentials)) {
/**
* 使用微信数据来创建一个新的用户
*/
$user = User::create([
"email" => $username,
"password" => bcrypt($password),
"openId" => $session_data['openId'],
]);
/**
* 使用新的用户来登录,用于返回token
*/
$token = auth()->attempt($credentials);
/**
* 返回token给用户
*/
return $this->respondWithToken($token);
}
return $this->respondWithToken($token);
}
这样,我们就实现了微信的自动登录。我们使用 wx.login 登录获得的 code 换取 session_key 以及 openId,并使用不变的 openId 拼接邮箱作为用户名,使用 openId 作为密码,来确保用户无需输入账号密码自动登录。
获取小程序码
我们如何获取小程序码?也非常简单,只需要添加如下代码即可
use EasyWeChat;
public function getCode(){
$miniProgram = EasyWeChat::miniProgram();
$reponse = $miniProgram->app_code->get("/pages/index/index");
return $response;
}
这样,我们就完成了基于 Laravel 的小程序后台的开发!后续的更多内容,你可以到 EasyWeChat 的官网去查看各 API 的调用方式。