简体   繁体   中英

API Platform authorization vs authentication

I'm developing an API using API Platform and I'm struggling with how I can secure the API.

My frontend application (a blog site) has content that don't require a user to log in to see (public content). To fetch this content from the API, I don't need to authenticate the user but I still need to authorize the application to prevent everybody from being able to call the API. Some example routes are:

GET /api/blogs
GET /api/blogs/{id}

A user can still log in to access other parts of the site (secured content). And for those API calls I need to authenticate the user to check their roles(admin or others). Some example routes are:

POST /api/users
POST /api/blogs

The official documentation suggested using JWT to authenticate but that would mean that users will have to log in to see the public content. In security.yaml I tried this:

access_control:
  - { path: ^/api/blogs, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  - { path: ^/api/users, roles: ROLE_ADMIN }

But then /api/blogs is whitelisted and everyone or any application can call it from the API.

Here's the full content of my security.yaml :

security:
  encoders:
    App\Entity\User:
      id: App\Security\PasswordEncoder

  providers:
    app_user_provider:
      entity:
        class: App\Entity\User
        property: email
  firewalls:
    dev:
      pattern: ^/(_(profiler|wdt)|css|images|js)/
      security: false

    main:
      pattern: ^/api/
      stateless: true
      anonymous: true
      provider: app_user_provider
      json_login:
        check_path: api_authenticate
        username_path: email
        password_path: password
        success_handler: lexik_jwt_authentication.handler.authentication_success
        failure_handler: lexik_jwt_authentication.handler.authentication_failure
      guard:
        authenticators:
          - lexik_jwt_authentication.jwt_token_authenticator

  access_control:
    - { path: ^/api/blogs, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/users, roles: ROLE_ADMIN }

My question is, what's the proper way to handle authorization and authentication in my situation? Is JWT enough for doing both? Do I need a special API user created in the database?

A "JSON Web Token" (JWT), is nothing else than a way for the client (browser) to tell the application of a "claim" (eg "I am John Appleseed, User Number 123" ) which the application can verify.

It can do so because the claim was produced and cryptographically signed by the application in the first place: any tampering with this claim and the application would know it's an invalid claim.

As such, JWT is useful only for authentication : verifying the user identity in the system. Eg: Who are you?

Authorization happens after successful authentication. Is the application determining from your identity what resources or operations do you have or do not have access to. Eg: Are you allowed to do this?

Typically, there are two ways of handling authorization in Symfony. You configure the access_control key on security.yaml , or you deal with it in your controllers if your requirements are more complex.

In your case, using JWT tokens and configuring access_control should be more than enough. You have public parts in your API, that any user can query ( IS_AUTHENTICATED_ANONYMOUSLY ), and private sections that only authenticated users can get to ROLE_ADMIN .

Further reading:

Blocking other sites (apps) from accessing your API is done by proper CORS (allowed origin) settings. This can be done on PHP (Symfony) level or on Nginx level, if you use Nginx as reverse proxy in Nginx / php-fpm combination.

If your API is only for server to server communication, you can also add some specific "sitekey hash" to headers or requests. Similar to when you requesting Google APIs. But this is pointles in frontend to backend communication as key would be visible and unsecure in frontend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM