$user->id, 'iat' => time(), 'exp' => time() + (2 * 7 * 24 * 60 * 60) ]; return JWT::encode($payload, Config::get('app.token_secret')); } /** * Unlink provider. */ public function unlink(Request $request, $provider) { $user = User::find($request['user']['sub']); if (!$user) { return response()->json(['message' => 'User not found']); } $user->$provider = ''; $user->save(); return response()->json(array('token' => $this->createToken($user))); } /** * Log in with Email and Password. */ public function login(Request $request) { $email = $request->input('email'); $password = $request->input('password'); $user = User::where('email', '=', $email)->first(); if (!$user) { return response()->json(['message' => 'Wrong email and/or password'], 401); } if (Hash::check($password, $user->password)) { unset($user->password); return response()->json(['token' => $this->createToken($user)]); } else { return response()->json(['message' => 'Wrong email and/or password'], 401); } } /** * Create Email and Password Account. */ public function signup(Request $request) { $validator = Validator::make($request->all(), [ 'displayName' => 'required', 'email' => 'required|email|unique:users,email', 'password' => 'required' ]); if ($validator->fails()) { return response()->json(['message' => $validator->messages()], 400); } $user = new User; $user->displayName = $request->input('displayName'); $user->email = $request->input('email'); $user->password = Hash::make($request->input('password')); $user->save(); return response()->json(['token' => $this->createToken($user)]); } /** * Login with Facebook. */ public function facebook(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'redirect_uri' => $request->input('redirectUri'), 'client_secret' => Config::get('app.facebook_secret') ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('GET', 'https://graph.facebook.com/v2.5/oauth/access_token', [ 'query' => $params ]); $accessToken = json_decode($accessTokenResponse->getBody(), true); // Step 2. Retrieve profile information about the current user. $fields = 'id,email,first_name,last_name,link,name'; $profileResponse = $client->request('GET', 'https://graph.facebook.com/v2.5/me', [ 'query' => [ 'access_token' => $accessToken['access_token'], 'fields' => $fields ] ]); $profile = json_decode($profileResponse->getBody(), true); // Step 3a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('facebook', '=', $profile['id']); if ($user->first()) { return response()->json(['message' => 'There is already a Facebook account that belongs to you'], 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->facebook = $profile['id']; $user->email = $user->email ?: $profile['email']; $user->displayName = $user->displayName ?: $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 3b. Create a new user account or return an existing one. else { $user = User::where('facebook', '=', $profile['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->facebook = $profile['id']; $user->email = $profile['email']; $user->displayName = $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } /** * Login with Google. */ public function google(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'client_secret' => Config::get('app.google_secret'), 'redirect_uri' => $request->input('redirectUri'), 'grant_type' => 'authorization_code', ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('POST', 'https://accounts.google.com/o/oauth2/token', [ 'form_params' => $params ]); $accessToken = json_decode($accessTokenResponse->getBody(), true); // Step 2. Retrieve profile information about the current user. $profileResponse = $client->request('GET', 'https://www.googleapis.com/plus/v1/people/me/openIdConnect', [ 'headers' => array('Authorization' => 'Bearer ' . $accessToken['access_token']) ]); $profile = json_decode($profileResponse->getBody(), true); // Step 3a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('google', '=', $profile['sub']); if ($user->first()) { return response()->json(['message' => 'There is already a Google account that belongs to you'], 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->google = $profile['sub']; $user->displayName = $user->displayName ?: $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 3b. Create a new user account or return an existing one. else { $user = User::where('google', '=', $profile['sub']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->google = $profile['sub']; $user->displayName = $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } /** * Login with LinkedIn. */ public function linkedin(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'client_secret' => Config::get('app.linkedin_secret'), 'redirect_uri' => $request->input('redirectUri'), 'grant_type' => 'authorization_code', ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('POST', 'https://www.linkedin.com/uas/oauth2/accessToken', [ 'form_params' => $params ]); $accessToken = json_decode($accessTokenResponse->getBody(), true); // Step 2. Retrieve profile information about the current user. $profileResponse = $client->request('GET', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address)', [ 'query' => [ 'oauth2_access_token' => $accessToken['access_token'], 'format' => 'json' ] ]); $profile = json_decode($profileResponse->getBody(), true); // Step 3a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('linkedin', '=', $profile['id']); if ($user->first()) { return response()->json(['message' => 'There is already a LinkedIn account that belongs to you'], 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->linkedin = $profile['id']; $user->displayName = $user->displayName ?: $profile['firstName'] . ' ' . $profile['lastName']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 3b. Create a new user account or return an existing one. else { $user = User::where('linkedin', '=', $profile['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->linkedin = $profile['id']; $user->displayName = $profile['firstName'] . ' ' . $profile['lastName']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } /** * Login with Twitter. */ public function twitter(Request $request) { $stack = GuzzleHttp\HandlerStack::create(); // Part 1 of 2: Initial request from Satellizer. if (!$request->input('oauth_token') || !$request->input('oauth_verifier')) { $stack = GuzzleHttp\HandlerStack::create(); $requestTokenOauth = new Oauth1([ 'consumer_key' => Config::get('app.twitter_key'), 'consumer_secret' => Config::get('app.twitter_secret'), 'callback' => $request->input('redirectUri'), 'token' => '', 'token_secret' => '' ]); $stack->push($requestTokenOauth); $client = new GuzzleHttp\Client([ 'handler' => $stack ]); // Step 1. Obtain request token for the authorization popup. $requestTokenResponse = $client->request('POST', 'https://api.twitter.com/oauth/request_token', [ 'auth' => 'oauth' ]); $oauthToken = array(); parse_str($requestTokenResponse->getBody(), $oauthToken); // Step 2. Send OAuth token back to open the authorization screen. return response()->json($oauthToken); } // Part 2 of 2: Second request after Authorize app is clicked. else { $accessTokenOauth = new Oauth1([ 'consumer_key' => Config::get('app.twitter_key'), 'consumer_secret' => Config::get('app.twitter_secret'), 'token' => $request->input('oauth_token'), 'verifier' => $request->input('oauth_verifier'), 'token_secret' => '' ]); $stack->push($accessTokenOauth); $client = new GuzzleHttp\Client([ 'handler' => $stack ]); // Step 3. Exchange oauth token and oauth verifier for access token. $accessTokenResponse = $client->request('POST', 'https://api.twitter.com/oauth/access_token', [ 'auth' => 'oauth' ]); $accessToken = array(); parse_str($accessTokenResponse->getBody(), $accessToken); $profileOauth = new Oauth1([ 'consumer_key' => Config::get('app.twitter_key'), 'consumer_secret' => Config::get('app.twitter_secret'), 'oauth_token' => $accessToken['oauth_token'], 'token_secret' => '' ]); $stack->push($profileOauth); $client = new GuzzleHttp\Client([ 'handler' => $stack ]); // Step 4. Retrieve profile information about the current user. $profileResponse = $client->request('GET', 'https://api.twitter.com/1.1/users/show.json?screen_name=' . $accessToken['screen_name'], [ 'auth' => 'oauth' ]); $profile = json_decode($profileResponse->getBody(), true); // Step 5a. Link user accounts. if ($request->header('Authorization')) { $user = User::where('twitter', '=', $profile['id']); if ($user->first()) { return response()->json(['message' => 'There is already a Twitter account that belongs to you'], 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->twitter = $profile['id']; $user->displayName = $user->displayName ?: $profile['screen_name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 5b. Create a new user account or return an existing one. else { $user = User::where('twitter', '=', $profile['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->twitter = $profile['id']; $user->displayName = $profile['screen_name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } } /** * Login with Foursquare. */ public function foursquare(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'client_secret' => Config::get('app.foursquare_secret'), 'redirect_uri' => $request->input('redirectUri'), 'grant_type' => 'authorization_code', ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('POST', 'https://foursquare.com/oauth2/access_token', [ 'form_params' => $params ]); $accessToken = json_decode($accessTokenResponse->getBody(), true); // Step 2. Retrieve profile information about the current user. $profileResponse = $client->request('GET', 'https://api.foursquare.com/v2/users/self', [ 'query' => [ 'v' => '20140806', 'oauth_token' => $accessToken['access_token'] ] ]); $profile = json_decode($profileResponse->getBody(), true)['response']['user']; // Step 3a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('foursquare', '=', $profile['id']); if ($user->first()) { return response()->json(array('message' => 'There is already a Foursquare account that belongs to you'), 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->foursquare = $profile['id']; $user->displayName = $user->displayName ?: $profile['firstName'] . ' ' . $profile['lastName']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 3b. Create a new user account or return an existing one. else { $user = User::where('foursquare', '=', $profile['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->foursquare = $profile['id']; $user->displayName = $profile['firstName'] . ' ' . $profile['lastName']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } /** * Login with Instagram. */ public function instagram(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'client_secret' => Config::get('app.instagram_secret'), 'redirect_uri' => $request->input('redirectUri'), 'grant_type' => 'authorization_code', ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('POST', 'https://api.instagram.com/oauth/access_token', [ 'body' => $params ]); $accessToken = json_decode($accessTokenResponse->getBody(), true); // Step 2a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('instagram', '=', $accessToken['user']['id']); if ($user->first()) { return response()->json(array('message' => 'There is already an Instagram account that belongs to you'), 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->instagram = $accessToken['user']['id']; $user->displayName = $user->displayName ?: $accessToken['user']['username']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 2b. Create a new user account or return an existing one. else { $user = User::where('instagram', '=', $accessToken['user']['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->instagram = $accessToken['user']['id']; $user->displayName = $accessToken['user']['username']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } /** * Login with GitHub. */ public function github(Request $request) { $client = new GuzzleHttp\Client(); $params = [ 'code' => $request->input('code'), 'client_id' => $request->input('clientId'), 'client_secret' => Config::get('app.github_secret'), 'redirect_uri' => $request->input('redirectUri') ]; // Step 1. Exchange authorization code for access token. $accessTokenResponse = $client->request('GET', 'https://github.com/login/oauth/access_token', [ 'query' => $params ]); $accessToken = array(); parse_str($accessTokenResponse->getBody(), $accessToken); // Step 2. Retrieve profile information about the current user. $profileResponse = $client->request('GET', 'https://api.github.com/user', [ 'headers' => ['User-Agent' => 'Satellizer'], 'query' => $accessToken ]); $profile = json_decode($profileResponse->getBody(), true); // Step 3a. If user is already signed in then link accounts. if ($request->header('Authorization')) { $user = User::where('github', '=', $profile['id']); if ($user->first()) { return response()->json(['message' => 'There is already a GitHub account that belongs to you'], 409); } $token = explode(' ', $request->header('Authorization'))[1]; $payload = (array) JWT::decode($token, Config::get('app.token_secret'), array('HS256')); $user = User::find($payload['sub']); $user->github = $profile['id']; $user->displayName = $user->displayName ?: $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } // Step 3b. Create a new user account or return an existing one. else { $user = User::where('github', '=', $profile['id']); if ($user->first()) { return response()->json(['token' => $this->createToken($user->first())]); } $user = new User; $user->github = $profile['id']; $user->displayName = $profile['name']; $user->save(); return response()->json(['token' => $this->createToken($user)]); } } }