Empty referrer error from cron Job when calling Endpoint with restricted API key

483 views
Skip to first unread message

Clayton Gibb

unread,
Aug 31, 2017, 4:06:45 PM8/31/17
to Google Cloud Endpoints
I have an App engine app + Cloud endpoints. I have configured a cron task  in the task queue to call one of the endpoints. The cron has an auth-constraint to admin.

All of this is working, however when I restrict the api key to certain domains, I get the following error when the cron is run:

Failed
check_errors {
  code: REFERER_BLOCKED
  detail: "Requests from referer <empty> are blocked."
}

It doesn't seem like I can add a referee header to the cron.yaml

apparently Google App Engine issues cron requests from the IP address 0.1.0.1.

so I could allow that ip, but I want to restrict api key by domain not i.p. and it doesn't seem like I can do both

Does anyone know a workaround to allow the cron job access to an api key restricted by domain?

Clayton Gibb

unread,
Aug 31, 2017, 6:20:30 PM8/31/17
to Google Cloud Endpoints
I found a work around for this:

Note: I see people referencing this in the docs:

"Calling Google Cloud Endpoints

You cannot call a Google Cloud Endpoint from a cron job. Instead, you should issue a request to a target that is served by a handler that's specified in your app's configuration file or in a dispatch file. That handler then calls the appropriate endpoint class and method."


Without further explanation or example that I could see.

I am however able to call my endpoints from a cron job, and it was working fine, other than the api key restraint issue. 

I read several comments on other posts that mention doing a servlet mapping, but without providing an example, so here is the workaround I found and example code for the servlet mapping.

Java Class

    import java.io.IOException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyServlet extends HttpServlet {
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
    // call your Endpoint Method here, or whatever you want
            resp.setContentType("text/plain");
            resp.getWriter().println("Hello, world");
        }
    }


web.xml

     <servlet>
            <servlet-name>cronServlet</servlet-name>
            <servlet-class>com.example.MyServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>cronServlet</servlet-name>
            <url-pattern>/cronServlet</url-pattern>
        </servlet-mapping>
    
    <security-constraint>
            <web-resource-collection>
                <web-resource-name>cronServletConstraint</web-resource-name>
                <url-pattern>/cronServlet</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>admin</role-name>
            </auth-constraint>
        </security-constraint>

cron.yaml

    cron:
    - description: myCron
      url: /cronServlet
      schedule: every 12 hours


Reply all
Reply to author
Forward
0 new messages