modify according jrperritt's suggestion
diff --git a/openstack/identity/v2/tokens/results.go b/openstack/identity/v2/tokens/results.go
index dc09357..3903e39 100644
--- a/openstack/identity/v2/tokens/results.go
+++ b/openstack/identity/v2/tokens/results.go
@@ -23,6 +23,10 @@
 
 	// Tenant provides information about the tenant to which this token grants access.
 	Tenant tenants.Tenant
+
+	// the owner user of token
+	UserName string
+	UserID   string
 }
 
 // Endpoint represents a single API endpoint offered by a service.
@@ -76,7 +80,7 @@
 
 // GetResult is the deferred response from a Get call.
 type GetResult struct {
-    gophercloud.Result
+	gophercloud.Result
 }
 
 // ExtractToken returns the just-created Token from a CreateResult.
@@ -136,3 +140,40 @@
 func createErr(err error) CreateResult {
 	return CreateResult{gophercloud.Result{Err: err}}
 }
+
+// ExtractToken returns the Token from a GetResult.
+func (result GetResult) ExtractToken() (*Token, error) {
+	if result.Err != nil {
+		return nil, result.Err
+	}
+
+	var response struct {
+		Access struct {
+			Token struct {
+				Expires string `mapstructure:"expires"`
+				ID      string `mapstructure:"id"`
+			} `mapstructure:"token"`
+			User struct {
+				ID   string `mapstructure:"id"`
+				Name string `mapstructure:"name"`
+			} `mapstructure:"user"`
+		} `mapstructure:"access"`
+	}
+
+	err := mapstructure.Decode(result.Body, &response)
+	if err != nil {
+		return nil, err
+	}
+
+	expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Token{
+		ID:        response.Access.Token.ID,
+		ExpiresAt: expiresTs,
+		UserID:    response.Access.User.ID,
+		UserName:  response.Access.User.Name,
+	}, nil
+}