-
-
Save jrtashjian/326f9ed7162988b651a035f7a724831b to your computer and use it in GitHub Desktop.
OAuth2 ESI Client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
EVEONLINE_KEY=**your application key** | |
EVEONLINE_SECRET=**your application secret** | |
EVEONLINE_REDIRECT_URI=http://yourapp.tld/auth/eve/callback/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Carbon\Carbon; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Support\Facades\Route; | |
class Character extends Model | |
{ | |
/** | |
* The attributes that are mass assignable. | |
* | |
* @var array | |
*/ | |
protected $fillable = [ | |
'user_id', | |
'character_id', | |
'character_name', | |
'corporation_id', | |
'alliance_id', | |
'token', | |
'refresh_token', | |
'expires_on', | |
'character_owner_hash', | |
'scopes', | |
]; | |
public function getTokenAttribute($value) | |
{ | |
return $this->expires_on > Carbon::now() ? $value : null; | |
} | |
public function getScopesAttribute() | |
{ | |
return explode(' ', $this->attributes['scopes']); | |
} | |
public function getImageUrlAttribute() | |
{ | |
return sprintf( | |
'https://imageserver.eveonline.com/Character/%s_512.jpg', | |
$this->character_id | |
); | |
} | |
public function getSwitchToRouteUrlAttribute() | |
{ | |
$current_character = Route::current()->parameter('character'); | |
$current_route = Route::currentRouteName(); | |
if (strpos($current_route, 'character') === false) { | |
return null; | |
} | |
return $this->character_id === $current_character->character_id | |
? null | |
: route($current_route, [ 'character' => $this->character_id ]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Setup the ESI API Requests with the proper cache for every request. | |
* | |
* @param \EsiClient\EsiClient\Api $api The Swagger API class constant we are using. | |
* @param string $access_token The access_token for authenticating API requests. | |
* | |
* @return \EsiClient\EsiClient\Configuration | |
*/ | |
function esiRequest($api, $access_token = '') | |
{ | |
$stack = \GuzzleHttp\HandlerStack::create(); | |
$stack->push( | |
new \Kevinrob\GuzzleCache\CacheMiddleware( | |
new \Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy( | |
new \Kevinrob\GuzzleCache\Storage\LaravelCacheStorage( | |
\Illuminate\Support\Facades\Cache::store() | |
) | |
) | |
), | |
'cache' | |
); | |
$httpClient = new \GuzzleHttp\Client(['handler' => $stack]); | |
$apiInstance = new $api($httpClient); | |
if ($access_token) { | |
$apiInstance->getConfig()->setAccessToken($access_token); | |
} | |
$apiInstance->getConfig()->setUserAgent('EVE-Industry-Dashboard/1.0.0/php'); | |
return $apiInstance; | |
} | |
/** | |
* @param \App\Character $character | |
* | |
* @return mixed | |
*/ | |
function getCharacterAccessToken(\App\Character $character) | |
{ | |
if (! $character->token) { | |
$provider = new \League\OAuth2\Client\Provider\GenericProvider([ | |
'clientId' => config('services.eveonline.client_id'), | |
'clientSecret' => config('services.eveonline.client_secret'), | |
'redirectUri' => config('services.eveonline.redirect'), | |
'urlAuthorize' => 'https://login.eveonline.com/oauth/authorize', | |
'urlAccessToken' => 'https://login.eveonline.com/oauth/token', | |
'urlResourceOwnerDetails' => 'https://login.eveonline.com/oauth/verify', | |
]); | |
try { | |
$refresh_token_data = $provider->getAccessToken('refresh_token', [ | |
'refresh_token' => $character->refresh_token, | |
]); | |
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $error) { | |
dd($error->getMessage()); | |
} | |
// Update Character with new access token | |
$character->token = $refresh_token_data->getToken(); | |
$character->expires_on = date('Y-m-d H:i:s', $refresh_token_data->getExpires()); | |
$character->save(); | |
} | |
return $character->token; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Auth; | |
use App\Http\Controllers\Controller; | |
use EsiClient\ApiException; | |
use EsiClient\EsiClient\Api\CharacterApi; | |
use EsiClient\EsiClient\Api\CorporationApi; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\Auth; | |
class EveAccountController extends Controller | |
{ | |
private $provider; | |
public function __construct() | |
{ | |
// https://docs.microsoft.com/en-us/outlook/rest/php-tutorial#implementing-oauth2 | |
// https://oauth2-client.thephpleague.com/usage/ | |
$this->provider = new \League\OAuth2\Client\Provider\GenericProvider([ | |
'clientId' => config('services.eveonline.client_id'), | |
'clientSecret' => config('services.eveonline.client_secret'), | |
'redirectUri' => config('services.eveonline.redirect'), | |
'urlAuthorize' => 'https://login.eveonline.com/oauth/authorize', | |
'urlAccessToken' => 'https://login.eveonline.com/oauth/token', | |
'urlResourceOwnerDetails' => 'https://login.eveonline.com/oauth/verify', | |
]); | |
} | |
public function redirectToCharacterProvider() | |
{ | |
return redirect( | |
$this->provider->getAuthorizationUrl([ | |
'scope' => implode(' ', config('services.eveonline.character_scopes')) | |
]) | |
); | |
} | |
public function handleProviderCallback(Request $request) | |
{ | |
try { | |
$access_token = $this->provider->getAccessToken('authorization_code', [ | |
'code' => $request->query('code'), | |
]); | |
$resource_owner = $this->provider->getResourceOwner($access_token)->toArray(); | |
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $error) { | |
dd($error->getMessage()); | |
} | |
$character_id = $resource_owner['CharacterID']; | |
try { | |
// Get public character details from ESI. | |
$CharacterApi = esiRequest(CharacterApi::class); | |
$character = $CharacterApi->getCharactersCharacterId($character_id); | |
} catch (ApiException $error) { | |
dd($error->getMessage()); | |
} | |
// Store public character details into the database. | |
Character::updateOrCreate( | |
[ 'character_owner_hash' => $resource_owner['CharacterOwnerHash'] ], | |
[ | |
'user_id' => Auth::id(), | |
'character_id' => $character_id, | |
'character_name' => $resource_owner['CharacterName'], | |
'corporation_id' => $character->getCorporationId(), | |
'alliance_id' => $character->getAllianceId(), | |
'token' => $access_token->getToken(), | |
'refresh_token' => $access_token->getRefreshToken(), | |
'expires_on' => date('Y-m-d H:i:s', $access_token->getExpires()), | |
'scopes' => $resource_owner['Scopes'], | |
] | |
); | |
// Get corporation information from ESI. | |
$CorporationApi = esiRequest(CorporationApi::class); | |
try { | |
$corporation = $CorporationApi->getCorporationsCorporationId($character->getCorporationId()); | |
} catch (ApiException $error) { | |
return "Exception when calling CorporationApi->getCorporationsCorporationId: " . $error->getMessage() . PHP_EOL; | |
} | |
// Store public corporation details into the database and link to character model. | |
Corporation::updateOrCreate( | |
[ 'id' => $character->getCorporationId() ], | |
[ | |
'name' => $corporation->getName(), | |
'ticker' => $corporation->getTicker(), | |
'description' => $corporation->getDescription(), | |
'member_count' => $corporation->getMemberCount(), | |
'tax_rate' => $corporation->getTaxRate(), | |
] | |
); | |
return redirect()->route('home'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'eveonline' => [ | |
'client_id' => env('EVEONLINE_KEY'), | |
'client_secret' => env('EVEONLINE_SECRET'), | |
'redirect' => env('EVEONLINE_REDIRECT_URI'), | |
'character_scopes' => env('EVEONLINE_SCOPES_CHARACTER', [ | |
'publicData', | |
]), | |
], |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Database\Migrations\Migration; | |
use Illuminate\Database\Schema\Blueprint; | |
use Illuminate\Support\Facades\Schema; | |
class CreateCharactersTable extends Migration | |
{ | |
/** | |
* Run the migrations. | |
* | |
* @return void | |
*/ | |
public function up() | |
{ | |
Schema::create('characters', function (Blueprint $table) { | |
$table->bigIncrements('id'); | |
$table->unsignedBigInteger('user_id'); | |
$table->unsignedBigInteger('character_id'); | |
$table->string('character_name'); | |
$table->unsignedBigInteger('corporation_id')->nullable(); | |
$table->unsignedBigInteger('alliance_id')->nullable(); | |
$table->text('token'); | |
$table->text('refresh_token'); | |
$table->timestamp('expires_on')->nullable(); | |
$table->text('scopes'); | |
$table->string('character_owner_hash')->unique(); | |
$table->timestamps(); | |
$table->index('user_id'); | |
$table->index('character_id'); | |
$table->index('corporation_id'); | |
$table->index('alliance_id'); | |
$table->foreign('user_id')->references('id')->on('users'); | |
}); | |
} | |
/** | |
* Reverse the migrations. | |
* | |
* @return void | |
*/ | |
public function down() | |
{ | |
Schema::dropIfExists('characters'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Route::get('/auth/eve', 'Auth\EveAccountController@redirectToCharacterProvider'); | |
Route::get('/auth/eve/callback', 'Auth\EveAccountController@handleProviderCallback'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment