Symfony2 で FOSRest および FOSOauthServer バンドル (... およびその他多数) を使用して RESTful Web サービスを開発しています。私の問題は、他のユーザーのアクセス トークンを使用すると、API が 403 ステータス コードではなく応答を返すことです。例えば:
データベースに2人のユーザーが保存されています
userA with tokenA userB with tokenB
リクエスト例 http://example.com/api/v1/userA/products?access_token=tokenB
現在の応答
{
products: {
0: { ... }
1: { ... }
}
}
しかし、ユーザー B のアクセス トークンを使用してユーザー A の製品を要求しています。提供されたアクセス トークンが製品の所有者のものであるかどうかを確認するにはどうすればよいですか??
私の security.yml ファイル:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
MY_ROLE:
# ...
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
SONATA:
- ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
admin:
pattern: /admin(.*)
context: user
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /admin/login
use_forward: false
check_path: /admin/login_check
failure_path: null
logout:
path: /admin/logout
anonymous: true
# FOSOAuthBundle and FOSRestBundle
oauth_token:
pattern: ^/oauth/v2/token
security: false
# oauth_authorize: commented because there are not oauth login form on this app
# pattern: ^/oauth/v2/auth
# Add your favorite authentication process here
api:
pattern: ^/api
fos_oauth: true
stateless: true
anonymous: false
# This firewall is used to handle the public login area
# This part is handled by the FOS User Bundle
main:
# ...
access_control:
# ...
# API (FOSRestBundle and FOSOAuthBundle)
- { path: ^/api, roles: [IS_AUTHENTICATED_FULLY] }
ApiBundle の routing.yml
# API Endpoints
app_api_user_get_products:
pattern: /{username}/products
defaults: { _controller: ApiBundle:User:getProducts, _format: json }
methods: GET
私の UserController.php
<?php
namespace App\ApiBundle\Controller;
Use App\MainBundle\Entity\Product;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ... more use statments
class UserController extends ApiController {
/**
* List user's products.
*
* @ApiDoc(
* resource = true,
* description="This method must have the access_token parameter. The parameters limit and offset are optional.",
* filters={
* {"name"="access_token", "dataType"="string", "required"="true"},
* {"name"="offset", "dataType"="integer", "default"="0", "required"="false"},
* {"name"="limit", "dataType"="integer", "default"="250", "required"="false"}
* },
* )
*
* @Annotations\QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing products.")
* @Annotations\QueryParam(name="limit", requirements="\d+", default="500", description="How many products to return.")
*
* @Annotations\View()
*
* @param User $user the request object
* @param ParamFetcherInterface $paramFetcher param fetcher service
*
* @return array
*/
public function getProductsAction(User $user, ParamFetcherInterface $paramFetcher, Request $request) {
// $offset = $paramFetcher->get('offset');
// $offset = null == $offset ? 0 : $offset;
// $limit = $paramFetcher->get('limit');
try {
// estructure and exclude fields strategy http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies
$data = array('products' => array());
foreach ($user->getCatalog() as $p) {
if ($p->getAvailable() == true) {
$product = $p->getProduct();
$data['products'][] = array(
'id' => $product->getId(),
'reference' => $product->getReference(),
'brand' => $product->getBrand(),
'description' => $product->getDescription(),
// ...
);
}
}
} catch (\Exception $e) {
throw new HttpException(Codes::HTTP_INTERNAL_SERVER_ERROR, $e->getTraceAsString());
}
// New view
$view = new View($data);
$view->setFormat('json');
return $this->handleView($view);
}
}
助けてくれてどうもありがとう!