{"id":20244769,"url":"https://github.com/renoki-co/hej","last_synced_at":"2025-04-07T16:19:00.764Z","repository":{"id":36973077,"uuid":"282196287","full_name":"renoki-co/hej","owner":"renoki-co","description":"Hej! is a simple authentication boilerplate for Socialite.","archived":false,"fork":false,"pushed_at":"2023-09-11T05:09:21.000Z","size":163,"stargazers_count":135,"open_issues_count":2,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T14:12:13.936Z","etag":null,"topics":["authentication","authentication-flow","facebook","github","gitlab","google","hej","laravel","package","packages","passport","php","register","social","social-accounts","socialite","socialite-provider","twitter"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/renoki-co.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"rennokki"}},"created_at":"2020-07-24T10:57:28.000Z","updated_at":"2024-12-14T11:39:13.000Z","dependencies_parsed_at":"2024-12-24T10:23:42.021Z","dependency_job_id":"c6525793-bcb7-4670-aa69-f6e4b18f72db","html_url":"https://github.com/renoki-co/hej","commit_stats":{"total_commits":108,"total_committers":6,"mean_commits":18.0,"dds":"0.32407407407407407","last_synced_commit":"6b5e2784ccdbf81be6f42d68d296136a98d73430"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":"renoki-co/laravel-package-skeleton","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renoki-co%2Fhej","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renoki-co%2Fhej/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renoki-co%2Fhej/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renoki-co%2Fhej/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renoki-co","download_url":"https://codeload.github.com/renoki-co/hej/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247685628,"owners_count":20979085,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authentication-flow","facebook","github","gitlab","google","hej","laravel","package","packages","passport","php","register","social","social-accounts","socialite","socialite-provider","twitter"],"created_at":"2024-11-14T09:17:20.262Z","updated_at":"2025-04-07T16:19:00.737Z","avatar_url":"https://github.com/renoki-co.png","language":"PHP","funding_links":["https://github.com/sponsors/rennokki"],"categories":[],"sub_categories":[],"readme":"Hej! - a Socialite authentication flow implementation\n=====================================================\n\n![CI](https://github.com/renoki-co/hej/workflows/CI/badge.svg?branch=master)\n[![codecov](https://codecov.io/gh/renoki-co/hej/branch/master/graph/badge.svg)](https://codecov.io/gh/renoki-co/hej/branch/master)\n[![StyleCI](https://github.styleci.io/repos/282196287/shield?branch=master)](https://github.styleci.io/repos/282196287)\n[![Latest Stable Version](https://poser.pugx.org/renoki-co/hej/v/stable)](https://packagist.org/packages/renoki-co/hej)\n[![Total Downloads](https://poser.pugx.org/renoki-co/hej/downloads)](https://packagist.org/packages/renoki-co/hej)\n[![Monthly Downloads](https://poser.pugx.org/renoki-co/hej/d/monthly)](https://packagist.org/packages/renoki-co/hej)\n[![License](https://poser.pugx.org/renoki-co/hej/license)](https://packagist.org/packages/renoki-co/hej)\n\nHej! is a simple authentication flow implementation for Socialite. Out-of-the-box, Hej! can help you login and register users using Socialite providers, or link and unlink social accounts, just by extending a controller.\n\n- [Hej! - a Socialite authentication flow implementation](#hej---a-socialite-authentication-flow-implementation)\n  - [🤝 Supporting](#-supporting)\n  - [🚀 Installation](#-installation)\n  - [🙌 Usage](#-usage)\n  - [Extending Controllers](#extending-controllers)\n    - [Provider whitelisting](#provider-whitelisting)\n    - [Custom Socialite Redirect \u0026 Retrieval](#custom-socialite-redirect--retrieval)\n    - [Registering new users](#registering-new-users)\n      - [Handling duplicated E-Mail addresses](#handling-duplicated-e-mail-addresses)\n      - [Filling the Social table](#filling-the-social-table)\n    - [Callbacks](#callbacks)\n    - [Redirects](#redirects)\n    - [Link \u0026 Unlink](#link--unlink)\n    - [Custom Authenticatable](#custom-authenticatable)\n  - [🐛 Testing](#-testing)\n  - [🤝 Contributing](#-contributing)\n  - [🔒  Security](#--security)\n  - [🎉 Credits](#-credits)\n\n## 🤝 Supporting\n\n**If you are using one or more Renoki Co. open-source packages in your production apps, in presentation demos, hobby projects, school projects or so, sponsor our work with [Github Sponsors](https://github.com/sponsors/rennokki). 📦**\n\n[\u003cimg src=\"https://github-content.s3.fr-par.scw.cloud/static/23.jpg\" height=\"210\" width=\"418\" /\u003e](https://github-content.renoki.org/github-repo/23)\n\n## 🚀 Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require renoki-co/hej\n```\n\nPublish the config:\n\n```bash\n$ php artisan vendor:publish --provider=\"RenokiCo\\Hej\\HejServiceProvider\" --tag=\"config\"\n```\n\nPublish the migrations:\n\n```bash\n$ php artisan vendor:publish --provider=\"RenokiCo\\Hej\\HejServiceProvider\" --tag=\"migrations\"\n```\n\n## 🙌 Usage\n\nFor the user (or any Authenticatable instance) you should add the `HasSocialAccounts` trait and the `Sociable` interface:\n\n```php\nuse RenokiCo\\Hej\\Concerns\\HasSocialAccounts;\nuse RenokiCo\\Hej\\Contracts\\Sociable;\n\nclass User extends Authenticatable implements Sociable\n{\n    use HasSocialAccounts;\n\n    //\n}\n```\n\nOut-of-the-box, it works with any Laravel application.\n\nAfter you have configured Socialite, the only thing to do is to point your desired redirect and callback paths to the package controller:\n\n```php\nRoute::get('/social/{provider}/redirect', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'redirect']);\nRoute::get('/social/{provider}/callback', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'callback']);\n\nRoute::middleware('auth')-\u003egroup(function () {\n    Route::get('/social/{provider}/link', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'link']);\n    Route::get('/social/{provider}/unlink', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'unlink']);\n});\n```\n\nThe paths can be any, as long as they contain a first parameter which is going to be the provider you try to authenticate with. For example, accessing this link will redirect to Github:\n\n```\nhttps://my-link.com/social/github/redirect\n```\n\n## Extending Controllers\n\nHej! is really flexible and does a lot of things in the background to register or login using Socialite.\n\nHowever, you need to extend the controller and you will then be able to replace some methods to customize the flow.\n\n```php\nuse RenokiCo\\Hej\\Http\\Controllers\\SocialController;\n\nclass MySocialController extends SocialController\n{\n    //\n}\n```\n\nThen you should point the routes to the new controller.\n\n### Provider whitelisting\n\nDue to the fact that the endpoints are opened to get any provider, you can whitelist the Socialite provider names that can be used:\n\n```php\n/**\n * Whitelist social providers to be used.\n *\n * @var array\n */\nprotected static $allowedSocialiteProviders = [\n    //\n];\n```\n\nFor example, allowing only Facebook and Github should look like this:\n\n```php\nprotected static $allowedSocialiteProviders = [\n    'facebook',\n    'github',\n];\n```\n\nIf one of the providers accessed via the URL is not whitelisted, a simple redirect is done automatically. However, you can replace it and redirect to your custom [redirect action](#redirects).\n\n### Custom Socialite Redirect \u0026 Retrieval\n\nWith Socialite, you can use `-\u003eredirect()` to redirect the user and `-\u003euser()` to retrieve it. You can customize the instances by replacing `getSocialiteRedirect` and `getSocialiteUser`.\n\nHere is the default configuration:\n\n```php\n\n/**\n * Get the Socialite direct instance that will redirect\n * the user to the right provider OAuth page.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @return mixed\n */\nprotected function getSocialiteRedirect(Request $request, string $provider)\n{\n    return $this-\u003esocialite\n        -\u003edriver($provider)\n        -\u003eredirect();\n}\n\n/**\n * Get the Socialite User instance that will be\n * given after the OAuth authorization passes.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @return \\Laravel\\Socialite\\AbstractUser\n */\nprotected function getSocialiteUser(Request $request, string $provider)\n{\n    return $this-\u003esocialite\n        -\u003edriver($provider)\n        -\u003euser();\n}\n```\n\n### Registering new users\n\nWhen the Social account that the user logged in is not registered within the database, it creates a new authenticatable model, but in order to do this, it should fill it with data.\n\nBy default, it fills in using Socialite Provider's given data and sets a random 64-letter word password:\n\n```php\n/**\n * Get the Authenticatable model data to fill on register.\n * When the user gets created, it will receive these parameters\n * in the `::create()` method.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return array\n */\nprotected function getRegisterData(Request $request, string $provider, $providerUser): array\n{\n    return [\n        'name' =\u003e $providerUser-\u003egetName(),\n        'email' =\u003e $providerUser-\u003egetEmail(),\n        'email_verified_at' =\u003e now(),\n        'password' =\u003e Hash::make(Str::random(64)),\n    ];\n}\n```\n\n#### Handling duplicated E-Mail addresses\n\nSometimes, it can happen for the users to have an account created with E-Mail address only, having no social accounts. A new social account with the same E-Mail address will trigger a new authenticatable record in the database on callback.\n\nFor this, a [Redirect](#redirects) is made to handle this specific scenario.\n\n#### Filling the Social table\n\nAfter registration or login, the Socialite data gets created or updated, either the user existed or not.\n\nBy default, it's recommended to not get overwritten, excepting for the fact you want to change the table structure and extend the `Social` model that is also set in `config/hej.php`.\n\n```php\n/**\n * Get the Social model data to fill on register or login.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return array\n */\nprotected function getSocialData(Request $request, string $provider, $model, $providerUser): array\n{\n    return [\n        'provider_nickname' =\u003e $providerUser-\u003egetNickname(),\n        'provider_name' =\u003e $providerUser-\u003egetName(),\n        'provider_email' =\u003e $providerUser-\u003egetEmail(),\n        'provider_avatar' =\u003e $providerUser-\u003egetAvatar(),\n    ];\n}\n```\n\n### Callbacks\n\nRight before the user is authenticated or registered successfully, there exist callback that trigger and you can replace them for some custom logic.\n\n```php\n/**\n * Handle the callback after the registration process.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $social\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return void\n */\nprotected function registered(Request $request, $model, $social, $providerUser)\n{\n    //\n}\n\n/**\n * Handle the callback after the login process.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $social\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return void\n */\nprotected function authenticated(Request $request, $model, $social, $providerUser)\n{\n    //\n}\n\n/**\n * Handle the callback after the linking process.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $social\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return void\n */\nprotected function linked(Request $request, $model, $social, $providerUser)\n{\n    //\n}\n\n/**\n * Handle the callback after the unlink process.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  string  $provider\n * @return void\n */\nprotected function unlinked(Request $request, $model, string $provider)\n{\n    //\n}\n```\n\n### Redirects\n\nYou are free to overwrite the actions' redirects within the controller:\n\n```php\nuse Illuminate\\Support\\Facades\\Redirect;\nuse Illuminate\\Support\\Facades\\Session;\n\n/**\n * Specify the redirection route after successful authentication.\n *\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterAuthentication($model)\n{\n    return Redirect::route('home');\n}\n\n/**\n * Specify the redirection route to let the users know\n * the authentication using the selected provider was rejected.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterProviderIsRejected(Request $request, $provider)\n{\n    return Redirect::route('home');\n}\n\n/**\n * Specify the redirection route to let the users know\n * the E-Mail address used with this social account is\n * already existent as another account. This is most often\n * occuring during registrations with Social accounts.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterDuplicateEmail(Request $request, $provider, $providerUser)\n{\n    return Redirect::route('home');\n}\n```\n\n### Link \u0026 Unlink\n\nPrior to creating new accounts or logging in with Socialite providers, Hej! comes with support to link and unlink Social accounts to and from your users.\n\nYou will need to have the routes accessible only for your authenticated users:\n\n```php\nRoute::middleware('auth')-\u003egroup(function () {\n    Route::get('/social/{provider}/link', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'link']);\n    Route::get('/social/{provider}/unlink', [\\RenokiCo\\Hej\\Http\\Controllers\\SocialController::class, 'unlink']);\n});\n```\n\nFurther, you may access the URLs to link or unlink providers.\n\nAdditionally, you may implement custom redirect for various events happening during link/unlink:\n\n```php\nuse Illuminate\\Support\\Facades\\Redirect;\nuse Illuminate\\Support\\Facades\\Session;\n\n/**\n * Specify the redirection route to let the users know\n * the social account is already associated with their account.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterProviderIsAlreadyLinked(Request $request, $provider, $model)\n{\n    return Redirect::route('home');\n}\n\n/**\n * Specify the redirection route to let the users know\n * the social account is associated with another account.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterProviderAlreadyLinkedByAnotherAuthenticatable(\n    Request $request, $provider, $model, $providerUser\n) {\n    return Redirect::route('home');\n}\n\n/**\n * Specify the redirection route to let the users know\n * they linked the social account.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $social\n * @param  \\Laravel\\Socialite\\AbstractUser  $providerUser\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterLink(Request $request, $model, $social, $providerUser)\n{\n    return Redirect::route('home');\n}\n\n/**\n * Specify the redirection route to let the users\n * they have unlinked the social account.\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  \\Illuminate\\Database\\Eloquent\\Model  $model\n * @param  string  $provider\n * @return \\Illuminate\\Http\\RedirectResponse\n */\nprotected function redirectToAfterUnlink(Request $request, $model, string $provider)\n{\n    return Redirect::route('home');\n}\n```\n\n### Custom Authenticatable\n\nWhen trying to login or register, the package uses the default `App\\User` as defined in `config/hej.php`. However, this can easily be replaced at the request level:\n\n```php\n/**\n * Get the model to login (or register).\n *\n * @param  \\Illuminate\\Http\\Request  $request\n * @param  string  $provider\n * @return string\n */\npublic function getAuthenticatable(Request $request, string $provider)\n{\n    return config('hej.default_authenticatable');\n}\n```\n\nFor example, you can change the model to authenticate as for different Socialite providers:\n\n```php\npublic function getAuthenticatable(Request $request, string $provider)\n{\n    if ($provider === 'medium') {\n        return \\App\\AnotherUser::class;\n    }\n\n    return config('hej.default_authenticatable');\n}\n```\n\n**Keep in mind that the model should also use the Trait and the Interface and be `Authenticatable`.**\n\n## 🐛 Testing\n\n``` bash\nvendor/bin/phpunit\n```\n\n## 🤝 Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## 🔒  Security\n\nIf you discover any security related issues, please email alex@renoki.org instead of using the issue tracker.\n\n## 🎉 Credits\n\n- [Alex Renoki](https://github.com/rennokki)\n- [All Contributors](../../contributors)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenoki-co%2Fhej","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenoki-co%2Fhej","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenoki-co%2Fhej/lists"}