thomasaull

Rest-API site profile

Recommended Posts

Thank you for the profile. 

I'm trying to move client vue part to another domain. In order to do that, i had to make a few modifications:

 

to Auth.php:

public static function preflight() 
{
	return "OK";
}

to Router.php:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Authorization, Content-Type');
.
.
  $r->addGroup('/auth', function (\FastRoute\RouteCollector $r)
  {
    $r->addRoute('OPTIONS', '', Auth::class . '@preflight');
.
.
  $r->addGroup('/test', function (\FastRoute\RouteCollector $r)
  {
    $r->addRoute('OPTIONS', '', Auth::class . '@preflight');

and change  axios.defaults.baseURL

but after login it stays as "guest" (User logged in: guest)

It seems that it's impossible to use session (wire('session')->login) in that situation.

 

Could you advice how to pass and re-use, for example, user ID, bypassing processwire session (may be through encoding it with JWT)?

 

Nikolay

 

 

 

Share this post


Link to post
Share on other sites
On 9/6/2018 at 9:30 AM, nicolant said:

 It seems that it's impossible to use session (wire('session')->login) in that situation. 

while the wire('session')->login() should work for this request, it is likely the session is already destroyed on the next one. For this case it might be feasible to store the user id in the jwt payload (like you suggested). Since I'm going to have this case in an upcoming project, I gave it a try this morning. Please check the following commit for the changes I did: https://github.com/thomasaull/RestApiProfile-Src/commit/2dbdc79aa952bece6926dbee896de0a4f434bb6a

I didn't test it with different domains though, so I'd be thankful if you could report back if it works for you! 🙂

Share this post


Link to post
Share on other sites

Hallo, I wanted to test this site profile and cloned PW 3.0.98 from git. Then cloned the site profile repo and installed PW without any issues. I issued the 2 composer commands to install dependencies.

Environment: Apache with PHP 7.0.29 FPM/FastCGI.

When I try to access api/test, I get the following error

Screenshot_2018-09-08_12-05-43.thumb.png.b6d56abe13abbda1b3c51a78fd7b55a4.png 

Looks like a namespace issue. I didn't change namespaces on any of the files included in the profile. My config.php is not namespaced.

Does anyone have an idea how I can overcome this?

EDIT: apache_request headers became available under FastCGI since 5.4.0 according to http://php.net/manual/en/function.apache-request-headers.php 
EDIT2: After some more investigation I found https://bugs.php.net/bug.php?id=70025. So it seems apache_request_headers is still not supported in PHP 7.0 FPM/CGI environment.
I added templates/inc/functions.php with contents of https://gist.github.com/rmpel/11583cfddfcc9705578428e3a2ee3dc1 and added require "{$config->paths->templates}inc/functions.php"; to api.php
This solved the problem :)-
 

Share this post


Link to post
Share on other sites
On 9/7/2018 at 12:42 PM, thomasaull said:

while the wire('session')->login() should work for this request, it is likely the session is already destroyed on the next one. For this case it might be feasible to store the user id in the jwt payload (like you suggested). Since I'm going to have this case in an upcoming project, I gave it a try this morning. Please check the following commit for the changes I did: https://github.com/thomasaull/RestApiProfile-Src/commit/2dbdc79aa952bece6926dbee896de0a4f434bb6a

I didn't test it with different domains though, so I'd be thankful if you could report back if it works for you! 🙂

It remembers userId after login, but not on next reload of content, when   if(wire('user')->isGuest())  in Auth.php returns true.

Instead in auth() it should again read userId from token, but since $decoded variable is available only in Router...

 

EDIT:

It seems that retrieved JWT should be kept in sessionStorage entirely client-side. In order to do that I'd have to use VuexPersist plugin.

I'd have to move setting of authorization header (in my case, axios.defaults.headers.common['Authorization'] = 'Bearer ' + this.$store.state.jwt) from mutations.js to Content.vue. Not sure though that it's an elegant way.

I forked your repo with modifications here:

https://github.com/nicolant/RestApiProfile

 

Share this post


Link to post
Share on other sites

The auth() and login() functions are usually just used once to login a user and obtain an JWT token. The token is currently stored in vuex and will be lost on reload. The /client folder is also just intended to get you started and give you a general idea how the jwt login process could work. Anyway I think you figured it out by now 😉

Share this post


Link to post
Share on other sites
On 9/8/2018 at 12:11 PM, gebeer said:

Hallo, I wanted to test this site profile and cloned PW 3.0.98 from git. Then cloned the site profile repo and installed PW without any issues. I issued the 2 composer commands to install dependencies.

Environment: Apache with PHP 7.0.29 FPM/FastCGI.

When I try to access api/test, I get the following error

Screenshot_2018-09-08_12-05-43.thumb.png.b6d56abe13abbda1b3c51a78fd7b55a4.png 

Looks like a namespace issue. I didn't change namespaces on any of the files included in the profile. My config.php is not namespaced.

Does anyone have an idea how I can overcome this?

EDIT: apache_request headers became available under FastCGI since 5.4.0 according to http://php.net/manual/en/function.apache-request-headers.php 
EDIT2: After some more investigation I found https://bugs.php.net/bug.php?id=70025. So it seems apache_request_headers is still not supported in PHP 7.0 FPM/CGI environment.
I added templates/inc/functions.php with contents of https://gist.github.com/rmpel/11583cfddfcc9705578428e3a2ee3dc1 and added require "{$config->paths->templates}inc/functions.php"; to api.php
This solved the problem :)-
  

@gebeer you can also try to replace apache_request_headers() with $_SERVER which should also work. This way you don't need the any additional functions

  • Like 1

Share this post


Link to post
Share on other sites

Also just as a heads up, I'm in the process of converting this site profile into a module, since I'm struggeling to keep it up to date on my sites and thus should be much easier to update in the future

  • Like 4

Share this post


Link to post
Share on other sites

@thomasaull Great that you are converting this into a module. It would be a muc better fit. That way we can add api funtionality to any site easily. Actually, I was thinking about converting your site profile to a module, too 🙂

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By louisstephens
      I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like:
      Services A - Service "A" 1 - Service "A" 2 - Service "A" 3 B - Service "B" 1 - Service "B" 2 - Service "B" 3 C - Service "C" 1 - Service "C" 2 - Service "C" 3 Has anyone achieved this type of functionality before?
    • By quickjeff
      Hey guys, 
      Looking for another dev to help on multiple processwire projects as well as some other PHP apps. 
      First project is a directory style site with lots of components to come, including stripe implementation  and other fun stuff.
      Need someone ASAP to help out. 
       
      Thanks.
    • By louisstephens
      I am wondering, how do you pass a variable into wire('page')->get() inside a function? I have been looking through the forums, but unfortunately I have not found the answer yet.
      My current set up is:
      function generateNewPages($parentPageName) { $p = new Page(); $p->template = "parent"; $p->parent = wire('pages')->get('/home/'); $p->name = $parentPageName; $p->title = $parentPageName; $p->of(false); $p->save(); $p2 = new Page(); $p2->template = "child"; $p2->parent = wire('pages')->get('$parentPageName'); $p2->name = "child"; $p2->title = "Child Page"; $p2->of(false); $p2->save(); } When I try to run it by passing in a title like generateNewPages('Demo');, "Demo" is created, but when it gets to the child page I get:
      Unknown Selector operator: '$' -- was your selector value properly escaped?
      Is there a way to pass the $parentPageName to "wire('pages')->get('$parentPageName')" ?
    • By Pixrael
      I have a technical question that maybe you can guide me to a solution/idea.
      I know an online tool that publishes product information and updates prices/inventories regularly from marketplaces such as Amazon, Ebay, etc. to a Wordpress website ... can get the orders information, auto-order it and send back the tracking numbers. All this is done through the Woocommerce API. They don't have an API or CSV option to access this features..
      Is it possible to create fake REST endpoints (a clone of WooCommerce) on my site to accept requests from that external website and process this data my way inside PW? The requests to a REST endpoint are POST like in regular forms submits?
      Sorry I don't have to much technical background about this
      https://woocommerce.github.io/woocommerce-rest-api-docs/?php#create-a-product https://woocommerce.github.io/woocommerce-rest-api-docs/?php#update-a-product https://woocommerce.github.io/woocommerce-rest-api-docs/?php#retrieve-an-order