我正在完成使用 FOSUserBundle、FOSResBundle 和 FOSoAuthBundle 开发具有常见端点的 API REST。
以并行的方式,我正在开发另一个symfony应用程序来使用这些服务,但我对如何通过API端点注册和登录用户有几个疑问。我的想法是让 2 个控制器引用它的路由(例如/login 和/register),并通过 api 端点执行此操作。
使用 FOSUserbundle 此操作很简单,但不知道如何通过 APRest 服务"消费"。
我知道这只是一半的答案,但我目前通过登录而不是注册来执行此操作(我不需要它)。
我正在使用Symfony 4和flex,但我认为它应该适用于3.4。我也在使用 json。
束
我为此使用的捆绑包(在 fosuser 等之上):
- JMS/serializer-bundle
- lexik/jwt-authentication-bundle
- Friendsofsymfony/rest-bundle
配置
福斯休息
fos_rest:
body_listener: true
param_fetcher_listener: force
format_listener:
enabled: true
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
view:
view_response_listener: 'force'
formats:
json: true
xml: false
rss: false
mime_types:
json: ['application/json', 'application/x-json']
routing_loader:
default_format: json
include_format: false
exception:
enabled: true
福斯用户
fos_user:
db_driver: orm
firewall_name: api
user_class: AppEntityUser
from_email:
address: admin@example.com
sender_name: Admin
JMS 序列化程序
jms_serializer:
visitors:
xml:
format_output: '%kernel.debug%'
莱克西克智威汤逊
您需要生成令牌并将其位置放在.env
文件中。更多信息和指南在这里。
lexik_jwt_authentication:
private_key_path: '%kernel.project_dir%/%env(JWT_PRIVATE_KEY_PATH)%'
public_key_path: '%kernel.project_dir%/%env(JWT_PUBLIC_KEY_PATH)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600 #whatever you like
token_extractors:
authorization_header: ~
cookie: ~
query_parameter: ~
安全
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
FOSUserBundleModelUserInterface: sha512 #probably use bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_login:
pattern: ^/login
stateless: true
anonymous: true
form_login:
check_path: /login
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/, role: IS_AUTHENTICATED_FULLY }
路线
login:
type: rest
resource: AppControllerLoginController
控制器
我做了一个登录控制器,它实际上只是一个占位符来覆盖路由
<?php
namespace AppController;
use FOSRestBundleControllerAnnotations;
use FOSRestBundleControllerFOSRestController;
use FOSRestBundleRoutingClassResourceInterface;
use FOSRestBundleControllerAnnotationsRouteResource;
/**
* @RouteResource("login", pluralize=false)
*/
class LoginController extends FOSRestController implements ClassResourceInterface
{
public function postAction()
{
throw new DomainException('You should never see this');
}
}
测试它
您可以向/login
发出 POST 请求,它应该返回一个令牌!
{
"username": "my_user",
"password": "passw0rd"
}
注册
我实际上还没有这样做,但我有一个足够简单的想法......
在 security.yaml 中打开注册路径
security:
firewalls:
api_register:
pattern: ^/register
anonymous: true
access_control:
- { path: ^/register$, role: IS_AUTHENTICATED_ANONYMOUSLY }
注册路由
registration:
type: rest
resource: AppControllerRegistrationController
编写控制器方法
- 获取请求数据
- 使用 FosUserManager 创建新用户 - https://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html