Search code examples
loopbackjsloopback

Getting a limit response from Loopback, when no authentication is provided


I can't find a way to do it in the docs, and I have looked into as well here on Stack Overflow. I want to show a user a limited view of my JSON response from the API, before they have logged in.

So, as an example, I have a e-book I want to sell online. I want them only to see a preview link (epubFile.notAuthoried) of the book when not logged in, and the full link (epubFile.authorized) of the book when logged in. Both links are represented in the same table.

[
  {
    "title": "string",
    "subTitle": "string",
    "isPublished": true,
    "publicationDate": "2017-10-20T11:07:31.258Z",
    "epubFile": {
      "notAuthorized": "filename-noauth.epub"
      "authorized": "filename-auth.epub"
    }
    "id": "string",
    "createdOn": "2017-10-20T11:07:31.258Z",
    "updatedOn": "2017-10-20T11:07:31.258Z"
  }
]

Is it even possible to filter out fields from the API Endpoints in loopback? Or do I need to build a new custom API Endpoint?


Solution

  • first you'll have to set the permissions on your find and findById methods to $everyone so that both authorized and unauthorized users can call them

    {     
      "name": "eBook",
       "base": "PersistedModel",
       [...]
       "acls": [
         "accessType": "READ",
         "principalType": "ROLE",
         "principalId": "$everyone",
         "permission": "ALLOW",
         "property":["find", "findById]
        ]
    }
    

    Next, you'll have to hook into the remote methods and modify the response depending on if hte user is logged in or not

    const previewProperites = ['title', 'subTitle', etc...]
    Ebook.afterRemote('find', (ctx, ebooks, next) => {
      // pseudo code
      if(!ctx.options.accessToken){
        // no user logged in, only keep preview properties
        ebooks.forEach(book => {
          // get the properties of the book
          var eBookProperties = Object.keys(book.__data);
    
          eBookProperties.forEach(bookProp =>{
            if(!previewProperties.some(pProp => pProp === bookProp)){
              // ebook property not in preview list, so remove it
              delete book.__data[bookProp]; // .__data is where loopback keeps its actual data
            }
          });
        });
      }
      next();
    }