openbuildings / jam-auth
这是一个为 Jam 设计的 Kohana Auth 驱动器
Requires
- php: ^7.1
- composer/installers: *
- kohana/auth: ^3.3.0
- kohana/core: ^3.3.0
- openbuildings/jam: ^0.6
Requires (Dev)
- facebook/php-sdk-v4: ^5.0
- kohana/database: ^3.3.0
- openbuildings/kohana-test-bootstrap: ^0.2
- phpunit/phpunit: ^7
README
这是一个 Kohana Auth 驱动器,用于 Jam,但它添加了一些 Auth ORM 模块中缺少的功能,例如使用不同的服务登录/注销,例如 Twitter、Facebook 和 Google。服务基础设施已经存在,但目前只有 Facebook 服务已实现。
安装
在您的 bootstrap.php 中启用模块
DOCROOT/bootstrap.php
Kohana::modules(array(
'jam-auth' => MODPATH.'jam-auth',
// ...
));
APPPATH/config/auth.php
return array(
'driver' => 'jam'
// In order to use facebook auth service
'services' => array(
'facebook' => array(
'enabled' => TRUE,
// Automatically check this service for login credentials if the user is not logged in
'auto_login' => FALSE,
// Attempt to create the user if he's logged in with the service, but the user does not yet exist
'create_user' => TRUE,
// Facebook login credentials
'auth' => array(
'appId' => '224919274252280',
'secret' => '4c891b816f1273442bdd7e1bac33f7e3'
),
),
),
);
您需要创建数据库表 - 提供了两个 sql 文件用于 mysql / postgre
- auth-schema-mysql.sql
- auth-schema-postgresql.sql
您可以使用以下命令创建用户、角色和令牌表
入门指南
默认的 Model_User 为您设置了一些字段
- id - 主键
- email - 带有电子邮件验证的字符串字段,唯一
- username - 带有用户名验证的字符串字段(字母、破折号和下划线),长度 3..32,必需
- password - 在保存时将自动散列(因此在保存之前,您可以在设置时检索实际密码)
- logins - 用户登录次数
- last_login - 上次登录日期
- last_login_ip - 用户上次登录的 IP 地址
- facbook_uid - 这由 Facebook 认证服务使用
- twitter_uid - 这由 Twitter 认证服务使用
您可以直接使用该模型,但您很可能想要自定义它,因此请创建一个位于 APPPATH/classes/model/ 文件夹中的 Model_User 文件。
APPPATH/classes/model/user.php
<?php defined('SYSPATH') OR die('No direct script access.');
class Model_User extends Model_Auth_User {
public static function initialize(Jam_Meta $meta)
{
// Initialize the parent - set fields and associations
parent::initialize($meta);
$meta->behaviors(array(
'sluggable' => Jam::behavior('Sluggable'),
));
// Add additional fields
$meta->fields(array(
'first_name' => Jam::field('string'),
'last_name' => Jam::field('string'),
));
}
}
要设置登录代码,您可以使用 jam auth 的 ->login() 方法,如下所示
APPPATH/views/session/form.php
<?php if (isset($message)): ?>
<div><?php echo $message ?></div>
<?php endif ?>
<form action="session/login">
<input type="text" name="username"/>
<input type="password" name="password"/>
<input type="checkbox" value="1" name="remember"/>
</form>
APPPATH/classes/controller/session.php
class Controller_Session extends Controller {
function action_login()
{
$request = $this->request;
$view = View::factory('session/form');
if ($request->method() === Request::POST)
{
// If the username / password is correct, login the user and return it, otherwise return FALSE
if ($user = Auth::instance()->login($request->post('username'), $request->post('password'), $request->post('remember')))
{
$view->set('message', 'You have successfully logged in '.$user->name());
}
else
{
$view->set('message', 'Username or password incorrect');
}
}
$this->response->body($view);
}
}
自动登录
自动登录使用 cookies 自动登录用户。
// By setting the "remember me" to TRUE, you create an auth token entry in the database with the corresponding cookie
$user = Auth::instance()->login($username, $password, TRUE);
// Which will be used by these methods to automatically login the user if the cookie matches the db entry
Auth::instance()->logged_in();
Auth::instance()->get_user();
Auth::instance()->auto_login();
服务也可以配置为用于自动登录,例如,如果 Facebook 认证服务配置具有 'auto_login' => TRUE,则任何 ->auto_login() 调用都尝试使用该服务来登录用户。但是请注意,这可能会给未登录用户的请求增加大量开销。
最好使用单独的方法使用每个服务进行登录,如下例中所述
使用服务登录
Jam Auth 也支持 Facebook 登录,Facebook API 已包含在 vendors 文件夹中。以下是一个使用 Facebook 的示例登录代码
APPPATH/classes/controller/session.php
class Controller_Session extends Controller {
function action_login_facebook()
{
$this->auth->login_with_service('facebook');
}
function action_complete_login_facebook()
{
if ($user = $this->auth->complete_login_with_service('facebook'))
{
$this->redirect(URL::site());
}
else
{
throw new Auth_Exception_Service('There was an error logging in through facebook');
}
}
}
->login_with_service() 将您重定向到 Facebook 的 "登录" URL。 ->complete_login_with_service() 与 ->login() 类似,在成功登录时返回已登录用户,失败时返回 FALSE。但是,您必须自己将用户登录到服务。对于 Facebook 来说,特别是这种方式是通过执行一个 "登录" 动作来实现的,然后返回到这个 URL (/session/login_facebook)。然后它会找出这是您的数据库中的哪个用户。您可以使用 'create_user' 配置选项控制是否自动创建用户(如果数据库中不存在)。
Facebook 模型扩展
为了从服务中加载所有必需的用户信息(您希望关于用户的信息不仅仅是电子邮件),您可以扩展模型的 load_service_values() 方法并编写特定的代码来处理提取该信息。例如
public function load_service_values(Auth_Service $service, array $user_data, $create = FALSE)
{
if ($service->name == 'facebook')
{
$email = Arr::get($user_data, 'email');
$this->set(array_filter(array(
'facebook_uid' => $user_data['id'],
'username' => URL::title(Arr::get($user_data, 'username', $user_data['name']), '-', TRUE),
'first_name' => Arr::get($user_data, 'first_name'),
'last_name' => Arr::get($user_data, 'last_name'),
'image' => 'http://graph.facebook.com/'.$user_data['id'].'/picture?type=large',
'email' => $email,
'facebook' => 'http://facebook.com/'.Arr::get($user_data, 'username', $user_data['id']),
)));
}
return $this;
}
忘记密码
忘记密码本身并未实现,但设置起来非常简单。
APPPATH/views/session/forgotten.php
<?php if (isset($message)): ?>
<div><?php echo $message ?></div>
<?php endif ?>
<form action="session/login">
<input type="text" name="email"/>
</form>
APPPATH/classes/controller/session.php
class Controller_Session extends Controller {
function action_send_forgotten()
{
$request = $this->request;
$view = View::factory('session/form');
if ($request->method() === Request::POST)
{
$user = Jam::find('user', $request->post('email'));
if ($user->loaded())
{
// Generate a special onetime token, that will expire in a week
$token = $user->generate_login_token();
mail($user->email, 'Forgotten Password', 'Click this link to login: '.URL::site(TRUE).'/session/login_token/'.$token->token);
$view->set('message', 'An email with instructions has been sent to '.$user->email);
}
else
{
$view->set('message', 'A user with this email was not found');
}
}
$this->response->body($view);
}
function action_login_token()
{
// Perform the actual login - if the login is successful - return the user, otherwise return FALSE
if ($user = $this->auth->login_with_token($this->request->param('id')))
{
$this->redirect(URL::site());
}
else
{
throw new Auth_Exception_Service('The token has expired or was incorrect');
}
}
}
注销
注销稍微复杂一些,因为它需要访问每个服务的网站进行注销,因此可能需要多次通过“注销”页面来完成。这会自动处理,但如果你有明确的重定向,它们可能不会按预期工作。示例注销代码
APPPATH/classes/controller/session.php
class Controller_Session extends Controller {
function action_destroy()
{
$this->auth->logout();
$this->redirect(URL::site());
}
}
许可证
jam-auth版权所有 © 2012-2013 OpenBuildings Ltd. 由Ivan Kerin开发。它是免费软件,可以根据LICENSE文件中指定的条款重新分发。