Skip to content

Instantly share code, notes, and snippets.

@elinardo10
Last active June 5, 2020 18:09
Show Gist options
  • Save elinardo10/648c895bc1dfc9f496a9b197b8016f87 to your computer and use it in GitHub Desktop.
Save elinardo10/648c895bc1dfc9f496a9b197b8016f87 to your computer and use it in GitHub Desktop.
Social Auth laravel API + Nuxt/VUE
socialLogin(context, { provider, token }) {
const url = `v1/login/${provider}`;
return this.$axios.$post(url, { token });
},
<?php
Route::post('login/{provider}', 'SocialController@socialLogin');
<?php
namespace App\V1\Auth\Controllers;
use App\V1\Auth\Services\SocialService;
use App\Http\Controllers\Controller;
use App\V1\Auth\Requests\AuthSocialLoginRequest;
class SocialController extends Controller
{
private $socialService;
public function __construct(SocialService $socialService)
{
$this->socialService = $socialService;
}
public function socialLogin($provider, AuthSocialLoginRequest $request)
{
$input = $request->validated();
return $this->socialService->socialLogin($provider, $input);
}
}
<template>
<div class="social-login">
<div class="social-login__login-with">
{{ loginWithText }}
</div>
<div class="d-flex align-items-center justify-content-between">
<BButton
variant="outline-secondary"
block
size="sm"
:disabled="spinner.facebook_login"
class="btn-facebook"
@click="facebookLogin()"
>
<BSpinner
v-if="spinner.facebook_login"
small
/>
<FontAwesomeIcon
v-else
:icon="['fab', 'facebook']"
/>
<span class="d-none d-sm-inline-block">Facebook</span>
</BButton>
<BButton
:id="googleCustomBtn"
variant="outline-secondary"
block
size="sm"
:disabled="spinner.google_login"
class="btn-google"
>
<BSpinner
v-if="spinner.google_login"
small
/>
<FontAwesomeIcon
v-else
:icon="['fab', 'google']"
/>
<span class="d-none d-sm-inline-block">Google</span>
</BButton>
</div>
<div class="social-login__ou">
<div class="social-login__ou_border" />
<span>Or continue with email</span>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import { has } from 'lodash';
export default {
name: 'SocialMediaLogin',
props: {
loginWithText: {
type: String,
default: 'Login with',
},
},
data() {
return {
googleCustomBtn: `googleCustomBtn_${this._uid}`,
spinner: {
facebook_login: false,
google_login: false,
},
};
},
mounted() {
this.startGoogleService();
},
methods: {
...mapActions('authentication', {
$_socialLogin: 'socialLogin',
}),
facebookLogin() {
// eslint-disable-next-line
FB.login((response) => {
if (has(response, 'authResponse.accessToken')) {
this.spinner.facebook_login = true;
this.$_socialLogin({ provider: 'facebook', token: response.authResponse.accessToken }).then((response) => {
this.$auth.setUserToken(response.access_token);
}).catch(() => {
this.spinner.facebook_login = false;
});
}
});
},
googleLogin(gToken) {
this.spinner.google_login = true;
this.$_socialLogin({ provider: 'google', token: gToken }).then((response) => {
this.$auth.setUserToken(response.access_token);
}).catch(() => {
this.spinner.google_login = false;
});
},
startGoogleService() {
const vm = this;
if (!window.gapi) {
return false;
}
window.gapi.load('auth2', function() {
// Retrieve the singleton for the GoogleAuth library and set up the client.
window.auth2 = window.gapi.auth2.init({
client_id: '1079458222560-6h3gpo9shsa0f3ijq4pkg7sac0r8tfcr.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
});
attachSignin(document.getElementById(vm.googleCustomBtn));
});
function attachSignin(element) {
window.auth2.attachClickHandler(element, {}, function(googleUser) {
const gu = googleUser.getAuthResponse(true);
const gToken = gu.access_token;
vm.googleLogin(gToken);
}, function(error) {
console.log(error);
});
}
},
},
};
</script>
<style
lang="scss"
scoped
>
.social-login {
margin-bottom: 10px;
}
.social-login__login-with {
font-size: 12px;
margin-bottom: 2px;
}
.social-login__ou {
align-items: center;
color: #afb2c0;
display: flex;
justify-content: center;
margin: 24px 0;
position: relative;
span {
background-color: #fff;
font-size: 14px;
padding: 0 5px;
z-index: 1;
}
}
.social-login__ou_border {
background-color: lighten(#afb2c0, 10%);
height: 1px;
position: absolute;
width: 100%;
}
.btn-facebook {
border-color: #afb2c0;
color: #afb2c0;
font-weight: normal;
margin: 0 2px 0 0;
&:hover,
&:focus {
background-color: #4671b8 !important;
border-color: #4671b8 !important;
color: #fff !important;
}
}
.btn-google {
border-color: #afb2c0;
color: #afb2c0;
font-weight: normal;
margin: 0 0 0 2px;
&:hover,
&:focus {
background-color: #b84444 !important;
border-color: #b84444 !important;
color: #fff !important;
}
}
</style>
<?php
namespace App\V1\Auth\Services;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Storage;
use App\V1\User\Models\User;
use App\V1\Auth\Models\SocialAuth;
use App\V1\Auth\Events\UserRegisteredEvent;
use App\V1\User\Resources\UserResource;
use App\V1\Traits\ResponseTrait;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
class SocialService
{
use ResponseTrait;
public function socialLogin($provider, $input)
{
$accessToken = $input['token'];
$socialUser = Socialite::driver($provider)->userFromToken($accessToken);
$user = $this->findOrCreateUser($provider, $socialUser);
$token = auth()->login($user);
$user = auth()->user();
return (new UserResource($user))->additional([
'access_token' => $token,
'token_type' => 'bearer',
]);
}
public function findOrCreateUser($provider, $socialUser)
{
$socialAccount = SocialAuth::where([
'provider_name' => $provider,
'social_id' => $socialUser->id
])->first();
if ($socialAccount) {
return $socialAccount->user;
}
$user = User::where('email', $socialUser->email)->first();
if (!$user) {
$user = User::create([
'first_name' => $socialUser->name,
'email' => $socialUser->email,
'password' => Str::random('64'),
]);
}
$user->socialAccounts()
->create([
'provider_name' => $provider,
'social_id' => $socialUser->id,
]);
return $user;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment