thephpleague / oauth2-linkedin

LinkedIn Provider for the OAuth 2.0 Client
MIT License
83 stars 37 forks source link

SignIn with LinkedIn dosen't work (Deprecated) #54

Open AlexGlushko opened 1 year ago

AlexGlushko commented 1 year ago

! Explanation: If you create linkedIn app now, you can't choose product "Sign In with LinkedIn" with scopes ['r_liteprofile', 'r_emailaddress']. Also you don't have credentials for access /me endpoint.

https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin (Deprecated)

New approch is here https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2

SignIn with OpenId was changed:

kiahreading commented 1 year ago

Hi @AlexGlushko, I am just about to implement with an app created post Aug 1. Does the fact that it is now "Sign In with LinkedIn using OpenID Connect" render this library unusable?

Separate to this, and a question to the contributors, is support for the new "Sign In with LinkedIn using OpenID Connect" something that could be on the horizon?

Thanks a lot!

AlexGlushko commented 1 year ago

@kiahreading for linkedin applications created before 1 August 23 all still working fine. Only for applications after that date you need separately call new endpoint /userinfo with bearer auth. I made this with use guzzlehttp lib

AlexGlushko commented 1 year ago

@kiahreading oh, and you need provide new scope fields [openid, email, profile] in your /connect/linkedin action

kiahreading commented 1 year ago

Hi @AlexGlushko, thank you very much for getting back.

Sorry for the questions, it's just that I have got other forms of login working with PHP League's libraries (eg. Google), but haven't had to make any code changes etc. That is a bit beyond my knowledge.

To make sure I understand you correctly, did you use this Library and make patches to the phpleague/oauth2-linkedin library itself or you wrote something completely separately without this library?

AlexGlushko commented 1 year ago

@kiahreading i still using this lib, but just modified my controller which calls on /connect/linkedin-check action (mentioned in docs for this lib) for call new endpoint provided by LinkedIn (/oauth/v2/userinfo)

izdrail commented 1 year ago

I've created my own class that is extending from the Provider and modified it according to this documentation https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2

<?php

namespace Cornatul\Social\Social;

use GuzzleHttp\RequestOptions;
use Illuminate\Support\Arr;
use Laravel\Socialite\Two\User;

class CustomLinkedInProvider extends \Laravel\Socialite\Two\LinkedInProvider
{
    public $scopes = ["profile","w_member_social", "openid", "email"];

    protected function getUserByToken($token)
    {
        return $this->getBasicProfile($token);
    }

    protected function getBasicProfile($token)
    {
        $response = $this->getHttpClient()->get('https://api.linkedin.com/v2/userinfo', [
            RequestOptions::HEADERS => [
                'Authorization' => 'Bearer '.$token,
                'X-RestLi-Protocol-Version' => '2.0.0',
            ],
            RequestOptions::QUERY => [
                'projection' => '(sub,name,picture,given_name,family_name,email,locale,email_verified)',
            ],
        ]);

        return (array) json_decode($response->getBody(), true);
    }

    /**
     * {@inheritdoc}
     */
    protected function mapUserToObject(array $user)
    {
        return (new User)->setRaw($user)->map([
            'id' => $user['sub'],
            'nickname' => null,
            'name' => $user['name'],
            'first_name' => $user['name'],
            'last_name' => $user['given_name'],
            'email' => $user['email'],
            'avatar' => $user['picture'],
            'avatar_original' => "",
        ]);
    }
}
luigimassa commented 9 months ago

it's simple: add new defaultScopes after create provider


        $provider = new LinkedIn([
            'clientId' => $this->getParameter('app.client_id'),
            'clientSecret' => $this->getParameter('app.client_secret'),
            'redirectUri' => $this->getParameter('app.redirect_uri'),
        ]);
        $provider->defaultScopes = ['w_member_social', 'email', 'profile', 'openid'];

        $authorizationUrl = $provider->getAuthorizationUrl();

        return new RedirectResponse($authorizationUrl);
izdrail commented 9 months ago

I guess this can be closed

lory-to commented 8 months ago

I guess this can be closed

I'd suggest not to close it but to adapt the code or release another plugin like oauth2-linkedin-oidc. @AlexGlushko request is still valid. For new apps, the current implementation won't work, and even if we can get access token using the suggested solutions above, methods like \League\OAuth2\Client\Provider\LinkedIn::getResourceOwnerDetailsUrl won't work.