Google authentication with Symfony 7
Tags: symfony, oauth
Published: 2024-02-05 20:39:04

I had some problems with Google authentication in Symfony 7.

Here are the steps I used to get it working. 

## Create a new application

`symfony new authdemo --version="7.0.*" --webapp
`
Create 2 controllers with `bin/console make:controller`.
`RootController` and `DashboardController`

Change the route for `RootController` from `/root` to `/`.
This will be our public page.

`/dashboard` should only be accessible for an authenticated user.

## Create the Google credentials

Go to your project on [Google cloud console](https://console.cloud.google.com/) and select 'APIs & Services'. 

On the credentials tab you can select 'create credentials' and then 'OAuth client ID'. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tlqmxkjy5zu4jawlhhnf.png)

In the next screen choose 'Web application' as application type.

Add `https://localhost:8000/login/check-google` to 'Authorized redirect URIs' and click 'create'

You now get a 'Client ID' and 'Client secret'. 

Create a `.env.local` file in the root of your project and add those values like this: 
```
GOOGLE_ID=<Paste you Google ID here>
GOOGLE_SECRET=<Paste your Google secret here>
```

## Install and configure the HWIOAuthBundle

You can find more detailed instructions [here](https://github.com/hwi/HWIOAuthBundle/blob/master/docs/1-setting_up_the_bundle.md)

Install the bundle: `composer require hwi/oauth-bundle` and execute the recipe to add the needed bundle and routing.

Change `config/packages/hwi_oauth.yaml` to look like this:

```yaml
hwi_oauth:
    firewall_names: [main]
    resource_owners:
        google:
            type:                google
            client_id:           '%env(GOOGLE_ID)%'
            client_secret:       '%env(GOOGLE_SECRET)%'
            scope:               "email profile"
```
The client_id and client_secret will be set from you environment variables. In this case the .env.local file we created in the previous step.

Now we need to update `config/packages/security.yaml`.

- Add the hwi_oauth provider
- Configure the main firewall to use the new provider with the correct settings
- Add access control rules to protect your application

```yaml
    providers:
        hwi_oauth.user.provider:
            id: hwi_oauth.user.provider

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern: ^/
            oauth:
               resource_owners:
                   google:          "/login/check-google"
               login_path:        /
               use_forward:       false
               failure_path:      /

               oauth_user_provider:
                   service: hwi_oauth.user.provider
               provider: hwi_oauth.user.provider

    access_control:
        - { path: ^/login, roles: PUBLIC_ACCESS }
        - { path: ^/connect, roles: PUBLIC_ACCESS }
        - { path: ^/(.+), roles: ROLE_USER }
        - { path: ^/$, roles: PUBLIC_ACCESS }

```

With those setting the root page should be public, but `/dashboard` should not be accessible. If you try to go to `/dashboard` you will be redirected to `/`.

Let's add a login link to the root page.

Add this in `templates/root/index.html.twig`:
```html
<a href="{{ path('hwi_oauth_service_redirect', {'service': 'google' }) }}">
    <span>Login with Google</span>
</a>
```

You need to add that route somewhere. I added this in `config/routes/hwi_oauth_routing.yaml`:
```yaml
google_login:
    path: /login/check-google
```


That is it!!

Now you should be able to login with google.
After logging in you should see your name in the Symfony Profiler. You should also be allowed to see `/dashboard` now.

Please let me know if you have any suggestions to improve this.