The Pingback specification currently covers mainly the use case without authentication. To avoid complex authentication delegation only Ajax requests via CORS and form post request are covered in this document. With enabled authentication the source value is no longer required. The endpoint fills the source value with the authenticated agent.
Beside the success codes we also have to define the behavior for two error codes.
The client didn't send the required authentication via Ajax or the supported authentication mechanisms don't support Ajax.
Authentication was successful but the endpoint doesn't allow Pingbacks with the given source or target agent.
Beside the success codes we also have to define the behavior for two error codes.
The server must send all required header fields defined by the CORS specification. The "Access-Control-Allow-Origin" field must contain the "Origin" request header field value as some browsers don't support post requests with the "*" wildcard. "Access-Control-Allow-Credentials" must contain "true" to support authentication. To enable the "Accept-Authentication" client header field [2] the "Access-Control-Allow-Headers" must be used.
Here an example:
Access-Control-Allow-Origin: https://www.example.org Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Accept-Authentication
If the client has send a "redirect_uri" data field the server must redirect after the client to the defined URI, after process the Pingback request. If an error has occurred the "error" field must be used to transfer the status code to the origin. Optional the "error_description" field can be used to describe the error more detailed.
Beside the success codes we also have to define the behavior for two error codes.
To allow authentication, the "withCredentials" properties must be set to true. Additional the "Accept-Authentication" can be used to tell the server which authentication mechanism the clients supports.
Also a form with the action pointing to the Pingback service can be used. Authentications with page flows must use this method. Additional to the fields defined by the Pingback spec a "redirect_uri" field must be given. The Pingback service must redirect after a successful or failed Pingback to this URI.
A Pingback request must not be used to share data beside the triples defined by the Pingback specification.
The response of the Pingback Ajax request via CORS must not contain any additional personalized data of the authenticated user.
A CORS request can be detected by cheching the Origin
HTTP Header Field.
First the client should try to use a Ajax request with CORS. If the server returns the unauthorized status code the client should fallback to the form submit method. If JavaScript is disabled the server should show only the form submit method.
pingback.Request.prototype.send = function(to, options) { var successCallback = (options['success'] !== undefined) ? options.success : function() {}; var errorCallback = (options['error'] !== undefined) ? options.error : function() {}; var data = {}; if(this.source() != null) data.source = this.source(); if(this.target() != null) data.target = this.target(); if(this.comment() != null) data.comment = this.comment(); var pingbackRequest = this; jQuery.support.cors = true; $.ajax({ url: to, type: "POST", xhrFields: { withCredentials: true }, data: data, headers: { 'Accept-Authentication': "WebID" }, success: function(data, textStatus, jqXHR) { successCallback(); }, error: function(jqXHR, textStatus, errorThrown) { if($.browser.msie) { if(errorThrown.number == -2147024891) pingbackRequest.sendFormSubmit(to); else errorCallback(); } else { if(errorThrown != "Forbidden") pingbackRequest.sendFormSubmit(to); else errorCallback(); } } }); }; pingback.Request.prototype.sendFormSubmit = function(to) { var html = '<form id="pingback-form" action="' + to + '" method="POST">'; if(this.source() != null) html += '<input type="hidden" name="source" value"' + this.source() + '" />'; if(this.target() != null) html += '<input type="hidden" name="target" value"' + this.target() + '" />'; if(this.comment() != null) html += '<input type="hidden" name="comment" value"' + this.comment() + '" />'; html += '</form>'; $("body").append(html); $("#pingback-form").submit(); };