2013-10-31 9 views
5

मैं अपनी वेबसाइट के लिए पुश सूचनाएं लागू करना चाहता हूं (जाहिर है केवल सफारी 7 के रूप में संगत ब्राउज़र में)। मैंने ऐप्पल प्रलेखन पढ़ा है और मैंने अपना आइकन सफलतापूर्वक बनाया है जिसमें मेरा आइकन.कॉन्ससेट, मेरा प्रमाणपत्र.p12, manifest.json और a website.json शामिल है। अब जब मैं पहली बार वेबसाइट पर जाता हूं तो मैं उपयोगकर्ता को अनुमति मांगना चाहता हूं। अगर वह इसे अनुमति देता है, तो मुझे पैकेज भेजना चाहिए। सब कुछ स्पष्ट है लेकिन मुझे नहीं पता कि कैसे चलना है।सफारी पुश अधिसूचना

मैं अपनी फ़ाइलों से अपने पुश पैकेज को कैसे बनाऊं? मैं इसे ठीक से कैसे हस्ताक्षर करूं? पैकेज हमेशा एक जैसा होना चाहिए ताकि मैं इसे अपने मैक पर हस्ताक्षर कर सकूं और केवल एक पैकेज में अपने सर्वर पर अपलोड कर सकूं।

आप इस तकनीक के साथ अनुभव किया है, मुझे पता है :)

उत्तर

2

एप्पल एक php फ़ाइल है कि आप हस्ताक्षर सहित अपने धक्का पैकेज बनाने के लिए उपयोग कर सकते हैं प्रदान करता है तो कृपया। https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/CompanionFile.zip

वैकल्पिक रूप से, आप push_package मणि, https://github.com/SymmetricInfinity/push_package का उपयोग कर सकते हैं, जिसे हमने zeropush.com के लिए सफारी पुश सूचनाओं को लागू करते समय विकसित किया था। अधिक जानकारी https://zeropush.com/blog/implementing-safari-push-notifications-in-osx-mavericks पर उपलब्ध हैं।

0

इस apple documentation और github repo, वे एक सफारी पुश नोटिफिकेशन के बनाने के लिए आवश्यक पर्याप्त जानकारी शामिल का पालन करें।

3

मैंने जावा में आरईएसटी एपीआई का उपयोग करके सफारी वेब पुश नोटिफिकेशन पर अनुमति मांगने के लिए सफलतापूर्वक पुश पैकेज बनाया है। इसके अलावा मैंने उन चरणों का पालन किया है जो ऐप्पल अधिकारियों द्वारा साइट पर प्रदान करते हैं।

कृपया पुश पैकेज बनाने के लिए नीचे दिए गए चरणों का पालन करें।

  1. अपने सेब खाते से अपनी वेब पुश अधिसूचना पी 12 प्रमाणपत्र बनाएं।

  2. pushPackage के लिए https का उपयोग करके अपना आरईएसटी एपीआई बनाएं जिसमें icon.iconset, आपका प्रमाणपत्र.p12, manifest.json और a website.json शामिल है। पी 12 प्रमाण पत्र वेब पुश अधिसूचना प्रमाण पत्र होना चाहिए।

  3. पुश पैकेज कैसे बनाएं: - कृपया जावा कोड नीचे देखें। मैंने जावा सर्वलेट का उपयोग करके पुश पैकेज बनाया है। जो 2 वेब सेवा अंत बिंदु प्रदान करते हैं।

  4. v1/pushpackage/webpushID

  5. v1/log

सर्वलेट जो अपने पुश पैकेज अनुरोध पर कार्रवाई जो सफारी पुश अधिसूचना विधि

SafariPushPakageAPI.java /* पुश पैकेज द्वारा भेजें आरईएसटी एपीआई हैंडलर */

import java.io.IOException; 
import java.io.OutputStream; 
import java.util.ArrayList; 
import java.util.Map; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.io.IOUtils; 
import org.apache.commons.lang.StringUtils; 

import com.safari.Packager; 

public class SafariPushPakageAPI extends HttpServlet{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    public static String ServerPath = null; 
    private static final String REQUEST_PERMISSION = "/v1/pushPackages/YOUR_WEB_PUSH_ID"; 
    private static final String REQUEST_ERRORLOG = "/v1/log"; 

    @Override 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     doRequest(request, response); 
    } 
// /v1/pushPackages/webpushID 
// /v1/log 
    @Override 
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     doRequest(request, response); 
    } 

    private void doRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     System.out.println("===>> SAFARI PUSH NOTIFICATION REQUEST"); 
     String path = request.getPathInfo(); 
     System.out.println("PATH ===>> "+path); 
     if(path == null){ 
      doRequestPermission(request, response); 
     }else if (path.equalsIgnoreCase(REQUEST_PERMISSION)){ 
      doRequestPermission(request, response); 
     }else if (path.equalsIgnoreCase(REQUEST_ERRORLOG)){ 
      doRequestShowErrorLog(request, response); 
     }else{ 
      doRequestPermission(request, response); 
     } 
    } 

    private void doRequestPermission(HttpServletRequest request,HttpServletResponse response) { 
     try{ 
      System.out.println("INSIDE REQUEST PERMISSION ==>>>"); 
      System.out.println(IOUtils.toString(request.getReader())); 
      String authToken = StringUtils.isBlank(request.getParameter("token")) ? "UserTokenRT124DFGH" : StringUtils.trimToEmpty(request.getParameter("token")); 
      System.out.println("=>>>>>>>>>> USER TOKEN =>>>>>>>>>> "+authToken); 
      @SuppressWarnings("deprecation") 
      String packagePath =request.getRealPath("pushPackage.raw/icon.iconset/"); // LOCATION WHERE YOUR PUSH PACKAGE FOLDER CONTAIN LOGOS AND website.json file 
      response.setContentType("application/zip"); 
      response.setHeader("Content-Disposition", "attachment;filename=\"pushpackage.zip\""); 
      OutputStream out = response.getOutputStream(); 
      out.write(Packager.createPackageFile(authToken,packagePath)); 
      response.flushBuffer(); 
     }catch(IOException ioe){ 
      ioe.printStackTrace(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private void doRequestShowErrorLog(HttpServletRequest request,HttpServletResponse response) { 
     try{ 
      System.out.println("ERROR LOG STARTED"); 
      System.out.println(IOUtils.toString(request.getReader())); 
      System.out.println("END"); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

} 

Packager.java

import java.io.DataInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import org.apache.commons.io.IOUtils; 
import org.json.JSONArray; 
import org.json.JSONObject; 

/** 
* 
* @author Ritesh 
*/ 
public class Packager { 

    final static String CERTIFICATE_PATH="PATH TO YOUR 12 CERTIFICATE"; 
    final static String CERTIFICATE_PASS="PASSWORD"; 

    static String getJSON(String authenticationToken) throws Exception { 
     JSONObject obj = new JSONObject(); 
     obj.put("websiteName", "WEB SITE NAME"); 
     obj.put("websitePushID", "WEB PUSH ID"); 
     obj.put("allowedDomains", new JSONArray()); 

     obj.getJSONArray("allowedDomains").put("https://TEST.EXAMPLE.net");//LIST OF DOMAINS ALLOW 

     obj.put("urlFormatString", "https://TEST.EXAMPLE.net/%@"); 
     obj.put("authenticationToken", authenticationToken); 
     obj.put("webServiceURL", "https://API.EXAMPLE.COM");//callback URL WITHOUT WEB SERVICE ENDPOINT NAME 

     return obj.toString(); 
    } 

    public static byte[] createPackageFile(String authenticationToken, String path) throws Exception { 

     System.out.println("packaging safari file with token: " + authenticationToken); 
     ZipHandler zip = new ZipHandler(); 
     File dir = new File(path); 

     for (File file : dir.listFiles()) {   
      InputStream is = new FileInputStream(file); 
      byte[] bytes = IOUtils.toByteArray(is); 
      zip.addFile("icon.iconset", file.getName(),bytes); 
     }  

     zip.addFile("", "website.json", getJSON(authenticationToken).getBytes()); 

     byte[] manifest = zip.manifest(); 
     zip.addFile("", "manifest.json", manifest); 

     zip.addFile("", "signature", sign(manifest)); 

     return zip.getBytes(); 

    } 

    static byte[] sign(byte bytesToSign[]) throws Exception { 
     return new PKCS7Signer().sign(CERTIFICATE_PATH,CERTIFICATE_PASS, bytesToSign); 
    } 

    /** 
    * Servlet handler , should listen on the callback URL (as in webServiceURL) 
    * @param requestPath 
    * @param req 
    * @param servletRequest 
    * @param servletResponse 
    * @throws Exception 
    */ 


    public static void main(String[] args) throws Exception { 
     Packager.createPackageFile("SafriNotifcation",""); 
    }    

} 

PKCS7Signer.java जो अपने हस्ताक्षर फ़ाइल बनाएँ।

import java.io.FileInputStream; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.Security; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.List; 

import org.bouncycastle.cert.X509CertificateHolder; 
import org.bouncycastle.cert.jcajce.JcaCertStore; 
import org.bouncycastle.cms.CMSProcessableByteArray; 
import org.bouncycastle.cms.CMSSignedData; 
import org.bouncycastle.cms.CMSSignedDataGenerator; 
import org.bouncycastle.cms.CMSTypedData; 
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.operator.ContentSigner; 
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; 
import org.bouncycastle.util.Store; 

public final class PKCS7Signer { 

    static { 
     try{ 
      Security.addProvider(new BouncyCastleProvider()); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    private KeyStore getKeystore(String storeLocation, String storePasswd) throws Exception { 
     if (storeLocation == null) { 
      System.out.println("Could not find store file (.p12)"); 
      return null; 
     } 
     // First load the keystore object by providing the p12 file path 
     KeyStore clientStore = KeyStore.getInstance("PKCS12"); 
     // replace testPass with the p12 password/pin 
     clientStore.load(new FileInputStream(storeLocation), storePasswd.toCharArray()); 
     return clientStore; 
    } 

    private X509CertificateHolder getCert(KeyStore keystore, String alias) throws Exception { 
     java.security.cert.Certificate c = keystore.getCertificate(alias); 
     return new X509CertificateHolder(c.getEncoded()); 
    } 

    private PrivateKey getPrivateKey(KeyStore keystore, String alias, String storePasswd) throws Exception { 
     return (PrivateKey) keystore.getKey(alias, storePasswd.toCharArray()); 
    } 

    public byte[] sign(String storeLocation, String storePasswd, byte[] dataToSign) throws Exception { 
     KeyStore clientStore = getKeystore(storeLocation, storePasswd); 

     if (clientStore == null) { 
      return null; 
     } 
     Enumeration aliases = clientStore.aliases(); 
     String alias = ""; 
     while (aliases.hasMoreElements()) { 
      alias = (String) aliases.nextElement(); 
      if (clientStore.isKeyEntry(alias)) { 
       break; 
      } 
     } 

     CMSTypedData msg = new CMSProcessableByteArray(dataToSign); // Data to sign 

     X509CertificateHolder x509Certificate = getCert(clientStore, alias); 
     List certList = new ArrayList(); 
     certList.add(x509Certificate); // Adding the X509 Certificate 

     Store certs = new JcaCertStore(certList); 

     CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 
     // Initializing the the BC's Signer 
     ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(
       getPrivateKey(clientStore, alias, storePasswd)); 

     gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder() 
       .setProvider("BC").build()).build(sha1Signer, x509Certificate)); 
     // adding the certificate 
     gen.addCertificates(certs); 
     // Getting the signed data 
     CMSSignedData sigData = gen.generate(msg, false); 
     return sigData.getEncoded(); 
    } 
} 

कृपया हाल ही में उपयोग उछाल वाले महल जार ध्यान दें हस्ताक्षर फ़ाइल बनाने के लिए bcprov-jdk15on-157.jar bcpkix-jdk15on-157.jar

  1. अपने जावास्क्रिप्ट लिखें आपके क्लाइंट साइड पेज.ट पर अनुमति प्राप्त करने के लिए सरल जावा स्क्रिप्ट शामिल है।

///

// सफारी वर डोमेन = "आपके वेब PUSH आईडी" के लिए;

function safariIniti() { 

    var pResult = window.safari.pushNotification.permission(domain); 

    if(pResult.permission === 'default') { 
     //request permission 
     requestPermissions(); 
    } else if (pResult.permission === 'granted') { 
     console.log("Permission for " + domain + " is " + pResult.permission); 
     var token = pResult.deviceToken; 
     // Show subscription for debug 
     console.log('Subscription details:'+token); 
    } else if(pResult.permission === 'denied') { 
     console.log("Permission for " + domain + " is " + pResult.permission); 
    } 
} 

function getToken(){ 

    // always start with a letter (for DOM friendlyness) 
    var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65)); 
    do {     
     // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90) 
     var ascicode=Math.floor((Math.random()*42)+48); 
     if (ascicode<58 || ascicode>64){ 
      // exclude all chars between : (58) and @ (64) 
      idstr+=String.fromCharCode(ascicode);  
     }     
    } while (idstr.length<32); 

    return (idstr); 
} 


function requestPermissions() { 

    var tokenVal = getToken(); 
    window.safari.pushNotification.requestPermission('WEb service url without end points',domain,{token:tokenVal}, 
function(subscription) { 


     console.log(subscription.permission); 
     console.log("PERMISSION ====>> "+subscription.permission); 
     if(subscription.permission === 'granted') { 
      //TODO 
     } 
     else if(subscription.permission === 'denied') { 
      // TODO: 
     } 
    }); 

} 
संबंधित मुद्दे