Check for token not being returned in JSON response (#91)

This avoid a potential nil pointer dereference since
JSON decoding can succeed with missing fields.
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index 4b362cc..36c9ce6 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -1,5 +1,6 @@
 package tokens
 
+import "errors"
 import "github.com/gophercloud/gophercloud"
 
 // Endpoint represents a single API endpoint offered by a service.
@@ -59,6 +60,10 @@
 		return nil, err
 	}
 
+	if s.Token == nil {
+		return nil, errors.New("'token' missing in JSON response")
+	}
+
 	// Parse the token itself from the stored headers.
 	s.Token.ID = r.Header.Get("X-Subject-Token")
 
diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go
index 195fa5a..27f3fdc 100644
--- a/openstack/identity/v3/tokens/testing/requests_test.go
+++ b/openstack/identity/v3/tokens/testing/requests_test.go
@@ -509,3 +509,24 @@
 		t.Errorf("Missing expected error from Revoke")
 	}
 }
+
+func TestNoTokenInResponse(t *testing.T) {
+	testhelper.SetupHTTP()
+	defer testhelper.TeardownHTTP()
+
+	client := gophercloud.ServiceClient{
+		ProviderClient: &gophercloud.ProviderClient{},
+		Endpoint:       testhelper.Endpoint(),
+	}
+
+	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
+		w.WriteHeader(http.StatusCreated)
+		fmt.Fprintf(w, `{}`)
+	})
+
+	options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"}
+	_, err := tokens.Create(&client, &options).Extract()
+	if err == nil {
+		t.Error("Create succeeded with no token returned")
+	}
+}