How to use different guard when login in from web or api in Laravel?












0















I am creating a Laravel (5.7) application for a mobile app. So I have an API and a Web Panel, both need to log in and each have a model. For Web login I use the User model (since this are operative roles) and another model Client for the users registered through the app.



I am using JWT to create auth tokens for the mobile app and using the regular login for the Web Panel.



The complication is that the default auth.php guard is web and if I use the (following) authenticate method from the API it goes to look to the users table, instead of the clients table, and its fixed when I change de default guard to api but the Web login then tries to look in the clients table.



So, in short I've tried to switch this default guards in many different ways but it just won't work. Some of the tests (that failed) I did are:




  • Changing the $guard variable in the login controller to web and setting api as default in auth.php

  • Overwriting the defaults auth.php guard in execution time using Config::set('auth.defaults.guard' , 'api'); or config('auth.defaults.guard' , 'api'); (and all its variations) in my API's authenticate method


This is my auth.php file



<?php

return [

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],

'api' => [
'driver' => 'session',
'provider' => 'clients'
],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => AppUser::class,
],

'clients' => [
'driver' => 'eloquent',
'model' => AppClient::class,
],
],

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],

];


My authenticate method in my ApiClientController.php



 public function authenticate(Request $request)
{
// config('auth.defaults.guard' , 'api'); // NOT WORKING!!
// Config::set('auth.guards.web.provider', 'clients'); // NOT WORKING!!
// Config::set('auth.providers.users.model', Client::class); // NOT WORKING!!
// config('auth.providers.users.model', Client::class); // NOT WORKING!!

$credentials = $request->only('phone', 'password');

try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 400);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}

Log::info("JWT Token: $token");

return response()->json(compact('token'));
}


Also, here is my Client model



<?php

namespace App;


use TymonJWTAuthContractsJWTSubject;
use IlluminateFoundationAuthUser as Authenticatable;

class Client extends Authenticatable implements JWTSubject
{

protected $hidden = [
'password', 'phone_verification_code', 'phone_verified_at'
];

public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return ;
}

}









share|improve this question























  • Try with token driver

    – sanu
    Nov 20 '18 at 17:57













  • Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

    – mkmnstr
    Nov 20 '18 at 18:21











  • You can try laravel.com/docs/5.7/passport which is built for multiple auth.

    – loic.lopez
    Nov 20 '18 at 18:38
















0















I am creating a Laravel (5.7) application for a mobile app. So I have an API and a Web Panel, both need to log in and each have a model. For Web login I use the User model (since this are operative roles) and another model Client for the users registered through the app.



I am using JWT to create auth tokens for the mobile app and using the regular login for the Web Panel.



The complication is that the default auth.php guard is web and if I use the (following) authenticate method from the API it goes to look to the users table, instead of the clients table, and its fixed when I change de default guard to api but the Web login then tries to look in the clients table.



So, in short I've tried to switch this default guards in many different ways but it just won't work. Some of the tests (that failed) I did are:




  • Changing the $guard variable in the login controller to web and setting api as default in auth.php

  • Overwriting the defaults auth.php guard in execution time using Config::set('auth.defaults.guard' , 'api'); or config('auth.defaults.guard' , 'api'); (and all its variations) in my API's authenticate method


This is my auth.php file



<?php

return [

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],

'api' => [
'driver' => 'session',
'provider' => 'clients'
],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => AppUser::class,
],

'clients' => [
'driver' => 'eloquent',
'model' => AppClient::class,
],
],

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],

];


My authenticate method in my ApiClientController.php



 public function authenticate(Request $request)
{
// config('auth.defaults.guard' , 'api'); // NOT WORKING!!
// Config::set('auth.guards.web.provider', 'clients'); // NOT WORKING!!
// Config::set('auth.providers.users.model', Client::class); // NOT WORKING!!
// config('auth.providers.users.model', Client::class); // NOT WORKING!!

$credentials = $request->only('phone', 'password');

try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 400);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}

Log::info("JWT Token: $token");

return response()->json(compact('token'));
}


Also, here is my Client model



<?php

namespace App;


use TymonJWTAuthContractsJWTSubject;
use IlluminateFoundationAuthUser as Authenticatable;

class Client extends Authenticatable implements JWTSubject
{

protected $hidden = [
'password', 'phone_verification_code', 'phone_verified_at'
];

public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return ;
}

}









share|improve this question























  • Try with token driver

    – sanu
    Nov 20 '18 at 17:57













  • Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

    – mkmnstr
    Nov 20 '18 at 18:21











  • You can try laravel.com/docs/5.7/passport which is built for multiple auth.

    – loic.lopez
    Nov 20 '18 at 18:38














0












0








0








I am creating a Laravel (5.7) application for a mobile app. So I have an API and a Web Panel, both need to log in and each have a model. For Web login I use the User model (since this are operative roles) and another model Client for the users registered through the app.



I am using JWT to create auth tokens for the mobile app and using the regular login for the Web Panel.



The complication is that the default auth.php guard is web and if I use the (following) authenticate method from the API it goes to look to the users table, instead of the clients table, and its fixed when I change de default guard to api but the Web login then tries to look in the clients table.



So, in short I've tried to switch this default guards in many different ways but it just won't work. Some of the tests (that failed) I did are:




  • Changing the $guard variable in the login controller to web and setting api as default in auth.php

  • Overwriting the defaults auth.php guard in execution time using Config::set('auth.defaults.guard' , 'api'); or config('auth.defaults.guard' , 'api'); (and all its variations) in my API's authenticate method


This is my auth.php file



<?php

return [

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],

'api' => [
'driver' => 'session',
'provider' => 'clients'
],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => AppUser::class,
],

'clients' => [
'driver' => 'eloquent',
'model' => AppClient::class,
],
],

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],

];


My authenticate method in my ApiClientController.php



 public function authenticate(Request $request)
{
// config('auth.defaults.guard' , 'api'); // NOT WORKING!!
// Config::set('auth.guards.web.provider', 'clients'); // NOT WORKING!!
// Config::set('auth.providers.users.model', Client::class); // NOT WORKING!!
// config('auth.providers.users.model', Client::class); // NOT WORKING!!

$credentials = $request->only('phone', 'password');

try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 400);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}

Log::info("JWT Token: $token");

return response()->json(compact('token'));
}


Also, here is my Client model



<?php

namespace App;


use TymonJWTAuthContractsJWTSubject;
use IlluminateFoundationAuthUser as Authenticatable;

class Client extends Authenticatable implements JWTSubject
{

protected $hidden = [
'password', 'phone_verification_code', 'phone_verified_at'
];

public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return ;
}

}









share|improve this question














I am creating a Laravel (5.7) application for a mobile app. So I have an API and a Web Panel, both need to log in and each have a model. For Web login I use the User model (since this are operative roles) and another model Client for the users registered through the app.



I am using JWT to create auth tokens for the mobile app and using the regular login for the Web Panel.



The complication is that the default auth.php guard is web and if I use the (following) authenticate method from the API it goes to look to the users table, instead of the clients table, and its fixed when I change de default guard to api but the Web login then tries to look in the clients table.



So, in short I've tried to switch this default guards in many different ways but it just won't work. Some of the tests (that failed) I did are:




  • Changing the $guard variable in the login controller to web and setting api as default in auth.php

  • Overwriting the defaults auth.php guard in execution time using Config::set('auth.defaults.guard' , 'api'); or config('auth.defaults.guard' , 'api'); (and all its variations) in my API's authenticate method


This is my auth.php file



<?php

return [

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],

'api' => [
'driver' => 'session',
'provider' => 'clients'
],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => AppUser::class,
],

'clients' => [
'driver' => 'eloquent',
'model' => AppClient::class,
],
],

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],

];


My authenticate method in my ApiClientController.php



 public function authenticate(Request $request)
{
// config('auth.defaults.guard' , 'api'); // NOT WORKING!!
// Config::set('auth.guards.web.provider', 'clients'); // NOT WORKING!!
// Config::set('auth.providers.users.model', Client::class); // NOT WORKING!!
// config('auth.providers.users.model', Client::class); // NOT WORKING!!

$credentials = $request->only('phone', 'password');

try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 400);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}

Log::info("JWT Token: $token");

return response()->json(compact('token'));
}


Also, here is my Client model



<?php

namespace App;


use TymonJWTAuthContractsJWTSubject;
use IlluminateFoundationAuthUser as Authenticatable;

class Client extends Authenticatable implements JWTSubject
{

protected $hidden = [
'password', 'phone_verification_code', 'phone_verified_at'
];

public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return ;
}

}






php laravel jwt restful-authentication multi-model-database






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 17:38









mkmnstrmkmnstr

383215




383215













  • Try with token driver

    – sanu
    Nov 20 '18 at 17:57













  • Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

    – mkmnstr
    Nov 20 '18 at 18:21











  • You can try laravel.com/docs/5.7/passport which is built for multiple auth.

    – loic.lopez
    Nov 20 '18 at 18:38



















  • Try with token driver

    – sanu
    Nov 20 '18 at 17:57













  • Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

    – mkmnstr
    Nov 20 '18 at 18:21











  • You can try laravel.com/docs/5.7/passport which is built for multiple auth.

    – loic.lopez
    Nov 20 '18 at 18:38

















Try with token driver

– sanu
Nov 20 '18 at 17:57







Try with token driver

– sanu
Nov 20 '18 at 17:57















Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

– mkmnstr
Nov 20 '18 at 18:21





Its still trying to look in the users table. "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone' in 'where clause' (SQL: select * from users where phone = 5517970659 limit 1)"

– mkmnstr
Nov 20 '18 at 18:21













You can try laravel.com/docs/5.7/passport which is built for multiple auth.

– loic.lopez
Nov 20 '18 at 18:38





You can try laravel.com/docs/5.7/passport which is built for multiple auth.

– loic.lopez
Nov 20 '18 at 18:38












1 Answer
1






active

oldest

votes


















0














The $request instance has a user method that takes one argument:



$request->user('apiguard');


If you are attempting authentication:



Auth::guard('apiguard')->attempt($credentials);





share|improve this answer


























  • It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

    – mkmnstr
    Nov 20 '18 at 18:35











  • Perhaps I used the wrong facade.

    – adam
    Nov 20 '18 at 19:46











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398562%2fhow-to-use-different-guard-when-login-in-from-web-or-api-in-laravel%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














The $request instance has a user method that takes one argument:



$request->user('apiguard');


If you are attempting authentication:



Auth::guard('apiguard')->attempt($credentials);





share|improve this answer


























  • It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

    – mkmnstr
    Nov 20 '18 at 18:35











  • Perhaps I used the wrong facade.

    – adam
    Nov 20 '18 at 19:46
















0














The $request instance has a user method that takes one argument:



$request->user('apiguard');


If you are attempting authentication:



Auth::guard('apiguard')->attempt($credentials);





share|improve this answer


























  • It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

    – mkmnstr
    Nov 20 '18 at 18:35











  • Perhaps I used the wrong facade.

    – adam
    Nov 20 '18 at 19:46














0












0








0







The $request instance has a user method that takes one argument:



$request->user('apiguard');


If you are attempting authentication:



Auth::guard('apiguard')->attempt($credentials);





share|improve this answer















The $request instance has a user method that takes one argument:



$request->user('apiguard');


If you are attempting authentication:



Auth::guard('apiguard')->attempt($credentials);






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 '18 at 19:46

























answered Nov 20 '18 at 18:25









adamadam

917811




917811













  • It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

    – mkmnstr
    Nov 20 '18 at 18:35











  • Perhaps I used the wrong facade.

    – adam
    Nov 20 '18 at 19:46



















  • It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

    – mkmnstr
    Nov 20 '18 at 18:35











  • Perhaps I used the wrong facade.

    – adam
    Nov 20 '18 at 19:46

















It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

– mkmnstr
Nov 20 '18 at 18:35





It works does log in but it does not generate the JWTAuth token, actually the variable $token returns true instead of the JWTAuth token.

– mkmnstr
Nov 20 '18 at 18:35













Perhaps I used the wrong facade.

– adam
Nov 20 '18 at 19:46





Perhaps I used the wrong facade.

– adam
Nov 20 '18 at 19:46




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53398562%2fhow-to-use-different-guard-when-login-in-from-web-or-api-in-laravel%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?