External Ajax Call - Security Error (for alerts and inbox)

Rjs37

Member
Apologies in advance for the detailed post.

I'm currently doing a small bit of integration work for someone and one of their requests was to get the xenforo navigation bar (Profile, Inbox, Alerts and Logout) on their website (wordpress).

They are using the Xenforo Integration WP plugin to unify the logins and that's given me an easy way to access the userinfo.

So what I did was basically copy the HTML source for the userbar and put it directly into the WP template. Obviously I would need to go populate the userinfo myself. I then included the styling and javascript files (jquery and xenforo.js). This mostly works (looks fine) except the ajax calls (inbox and alerts) fail with this: Security error occurred. Please press back, refresh the page, and try again.

I found this is because of it expecting _xfToken. After some digging I found how this was generated and included it into the userinfo array and spat it out into the source wherever it was referenced.

However when using Firebug to watch the ajax call (for either inbox or alerts) I can see it's not including _xfToken as one of the parameter:
http://website.com/forum/index.php?...website/&_xfNoRedirect=1&_xfResponseType=json

I've taken a long look at the xenforo.js file which leads me to a variable called XenForo._csrfToken which seems to be blank at the point it's used (when in WP). But I can't see where this variable is meant to be initialized as most of my alerts weren't firing.

Is what I'm attempting to do even possible? And if so I would really appreciate a little help in getting the ajax call to include the csrfToken that I have.

Alternatively
The other option I have briefly read about involved rendering the templates but as the navigation template includes several sub-templates I weren't sure how this would affect it plus there appeared to be a lot of variables that would need to be defined therefore complicating matters.
 
I apologise for the bump but it is for a good reason (I have a different question).

I've decided to attempt doing this by registering the template. (the alternative option I gave in my post above)

It seems to have worked except the urls are incorrect (relative to the forum's location and not the site's) and the ajax calls are still failing (might just be because of urls being wrong). It also looks like I need to pass it some more variables (I just passed it visitor for now).

Any ideas about how I can make the links relative from my site whilst it's rendering the template?

Only other thing i can think of is string replace on the template output but I'd have to do that on the hrefs, src's and possible a couple of other attributes too.
 
If you're using a XenForo template and the links are relative to XenForo, rather than your site, then I imagine that the template links look something like:

<a href="{xen:link account/preferences}">Preferences</a>

Try forming your URLs like this:

<a href="{xen:link full:account/preferences}">Preferences</a>
 
If you're using a XenForo template and the links are relative to XenForo, rather than your site, then I imagine that the template links look something like:

<a href="{xen:link account/preferences}">Preferences</a>

Try forming your URLs like this:

<a href="{xen:link full:account/preferences}">Preferences</a>
I think that'll just give an absolute (rather than relative) URL to account/preferences - it won't change the directory.
 
An absolute url would be exactly what I need. However as I think James was alluding to it's basing it off the current url so it's linking to http://website.com/account/preferences when I'm on the website. And http://website.com/forum/account/preferences when I'm on the forum. However I need the url to always be the forum.

Worst case scenario though, now that I have the full url doing a string replace on the template output would be pretty easy. i.e. website.com with website.com/forum

Though obviously it would be preferable to get Xenforo to output it correctly.
 
If you're integrating the site with XenForo, do you have access to XenForo's autoloader and classes?

If so, you may be able to rewrite the XenForo_Link class to something along the lines of:

if(URL == 'website.com')
{
append 'forum' before route
}
 
Cheers I'll give that a try tomorrow evening :). Thanks for pointing me in the right direction. Will be interesting to see if the ajax calls will work once it has the correct urls lol.

Yeah I have access to the autoloader. The site is actually using someone else's integration code (a wordpress plugin that someone on here probably developed).

Though the intialization code looks pretty much identical to the code I was working on when Xenforo first started up so it was pretty easy to pick it up. Had to add to it to be able to do the template rendering in the first place ;).
 
Okay I got the links sorted by using canonical: instead of full: Didn't need to use Xenforo_Link after all.

However I still have two issues:

1) I can't seem to use canonical in the image paths. It has @imagePath/xenforo/xenfocus/user_profile.png as the src. Any suggestions on what I can do with this?

2) That pesky security error has come back when going to Inbox or Alerts: "Security error occurred. Please press back, refresh the page, and try again." On the line above it says undefined.

In firebug the request doesn't seem to be including the _xfToken (same as when I was doing the html manually) which I assume is why it is failing the security check. I thought I had cracked it as I noticed there was a section of js just before the closing body tag, but including it doesn't seem to have had any impact.

This is the url it is firing at (if it helps): website.com/forum/index.php?conversations/popup&&_xfRequestUri=/website.com/&_xfNoRedirect=1&_xfResponseType=json

I can see that there is a double &&. I'm assuming that the token should be appearing there.
 
Concerning problem 1 I've come close to a solution but not quite managed to get the right combination.

{xen:link canonical:{xen:property imagePath}/xenforo/xenfocus/user_profile.png} and
{xen:link canonical:@imagePath/xenforo/xenfocus/user_profile.png}
both cause an error when trying to save the template

{xen:helper fullUrl, '{xen:property imagePath}/xenforo/xenfocus/user_profile.png', 1} works for the forum but behaves how full: did earlier in the thread when on the website (excludes the forum directory).

I really don't have a clue concerning the second problem. I'm not sure why the js isn't passing the token to the ajax call.
 
Just a tip - if you want to stop smilies appearing in your code - wrap it in [ code ] [/ code ] tags (remove spaces). (y)

Code:
{xen:link canonical:{xen:property imagePath}/xenforo/xenfocus/user_profile.png}

If you want to add formatting to the code, to highlight sections or changes, just use [ code=rich ] e.g.

Rich (BB code):
{xen:link canonical:{xen:property imagePath}/xenforo/xenfocus/user_profile.png}
 
Thank you for pointing that out Clickfinity.

I've managed to solve my image url problem by using a couple of string replaces. Not a neat solution but it works.

However this ajax issue still has me stumped. I'm far from a javascript developer so I'm having to feel may way through this issue as best I can.

Inside xenforo.js is this section of javascript:
Code:
XenForo._csrfToken&&(b=XenForo.ajaxDataPush(b,"_xfToken",XenForo._csrfToken));

If I add an alert before that section of code I can see that XenForo._csrfToken is blank/does not exist. However I can see the same variable defined just before the closing body tag (via the page_container_js_body template) just fine.

How does it get from the page_container_js_body template (where the token is defined) into the xenforo.js file? As far as I could tell XenForo is meant to be some sort of globally defined variable that should be accessible from xenforo.js, however it doesn't seem to be.

The only errors message I receive is as follows:
undefined:
Security error occurred. Please press back, refresh the page, and try again.


I know it's because it can't find te csrfToken variable but I can't see why it's not able to access it.
 
The CSRF token is accessible using JavaScript via this code:
XenForo._csrfToken

If you open your developer tools, go to console, type it in, it'll return your CSRF.

It should be globally available.
 
Thanks!

I didn't know I could actually do that. I'm used to debugging html and css with firebug but never for js :D.

I've finally found what the issue was. I was heading in the right direction when I included that page container js template however there was a js error prventing it from working. Your suggestion to check the console helped point me in the right direction. I noticed there was a js error. It was crashing because of this:

Code:
now: ,

Turned out I just needed to pass the server time variable to the code calling the template. After that it started working great. I should have looked at the JS error before but we had some originally which had nothing to do with xenforo and I thought this was the same error. Thanks again.
 
Top Bottom